/*   ---------------------------------------------------
**
**   DspLoad - display load types
**
**   ---------------------------------------------------
**   History : Created  16/04/92  by  LFMartha
**                                    Eduardo Corseuil
**                                    Vinicius Samu
**                                    Adriane Cavalieri
**
**   Modified: 17/Mar/94  by LFMartha
**       Created functions to display support reactions.
**
**   Modified on 12-Feb-98 by LFMartha.
**       When created function GraArc and changed display of moment circle.
**       Changed arrow display to fill area.
**
**   Modified on 09-Feb-99 by LFMartha.
**       Version 2.04:
**       Modified displaying of distributed member loading:
**       global direction loading is drawn in its actual vector
**       direction.
**       Fixed display of longitudinal component.
**
**   Modified on 29-May-99 by LFMartha.
**       Version 2.05:
**       Decreased display distance between member and transversal load 
**       when there is no longitudinal load or it is on the other side.
**       Before this distance was half of the longitudinal load 
**       characteristic size (size_lold).  Now the distance is one 
**       third of this size.
**
**   Modified on 16-Feb-2000 by LFMartha.
**       Version 2.06: When created thermal loading.
**       Created function DspThermalLoad and local functions to display 
**       heating and cooling loading.
**       Created load and reaction values visibility flags: added
**       option to display load and reaction values.
**       Added text size argument to entry point functions.
**
**   Modified on 03-Apr-2000 by LFMartha.
**       Version 2.07:
**       Increased the shift of displayed values of vertical forces
**       and reactions from 0.10 of force size to 0.15 of force size.
**
**   Modified on 15-Jan-2001 by LFMartha.
**       Version 2.09:
**       Created member end moments loading: created function DspMEndMomLoad.
**       Modified display of prescribed displacement support such that
**       each support constraint is displayed separetely: added offset
**       arguments to functions DspSupPrescrDispl and DspSupReact.
**       Deleted size arguments in display functions.
**       Created global function DspUtlDefOrientation, replacing
**       local function DefOrientation.
**       Revised text shift display: some GRA_BASE_RIGHT text alignments
**       were replaced by GRA_SOUTH_EAST and some GRA_BASE_LEFT were
**       replaced by GRA_SOUTH_WEST.
**
**   Modified on 13-Nov-2001 by LFMartha.
**       Version 2.10:
**       Modified display of reaction forces and moments such that
**       a dash line is draw in the center of arrow.
**
*/


#include <stdio.h>
#include <math.h>
#include <string.h>

#include "gblvar.h"
#include "dsp_att.h"
#include "gra.h"
#include "color.h"
#include "units.h"

#define sin60        (0.8660254)

enum {
 MEMBER_INI,
 MEMBER_CTR,
 MEMBER_END
};

#ifndef PI
#define PI 3.1416
#endif

extern char UnitsNames[NUM_UNIT_SYMBS][30];


/*  PROTOTYPES OF INTERNAL FUNCTIONS */

static void DspNodeHor_1     ( Tpoint *, double );
static void DspNodeHor_2     ( Tpoint *, double );
static void DspNodeVert_1    ( Tpoint *, double );
static void DspNodeVert_2    ( Tpoint *, double );
static void DspNodeMom_1     ( Tpoint *, double );
static void DspNodeMom_2     ( Tpoint *, double );

/*  Internal variables  */

static double   size_n;      /* reference size for nodal forces       */
static double   size_m;      /* reference size for nodal moments      */
static double   size_txt;    /* reference size for load values        */


#define NNarrowPts   6
static Tpoint Narrow1[NNarrowPts] =  { {  0.000,  0.000 },
                                       {  0.600,  0.000 },
                                       {  0.600, -0.100 },
                                       {  1.000,  0.000 },
                                       {  0.600,  0.100 },
                                       {  0.600,  0.000 } };

/*
** Auxiliary variables for displaying load and reaction values.
*/
static char dvalue[32];
static char dtext[32];


/*                                           **
**  This function displays the nodal forces  **
**                                           */

void DspLoadNod (

 Tpoint *p,      /* Point location where the forces will be displayed */
 double px,      /* The horizontal force value                        */
 double py,      /* The vertical force value                          */
 double mz,      /* The moment value                                  */
 int    colour)  /* Colour's forces draw                              */

{

  /* If the force exists and according to its signal,
     call the proper function to display the force    */

  if ( px || py || mz )
  {
    size_txt = dsp_sizetxt;
    GraSetTextHeight( size_txt );

    GraSetLineColor (colour);
    GraSetFillColor (colour);
    GraSetTextColor (colour);

    /* set the nodal force and moment sizes */
    size_n = dsp_sizenf;
    size_m = dsp_sizemom;

    if (px)
    {
      if ( px>0 )
       DspNodeHor_1 (p, px);
      else
       DspNodeHor_2 (p, px);
    }

    if (py)
    {
      if ( py>0 )
        DspNodeVert_1 (p, py);
      else
        DspNodeVert_2 (p, py);
    }

    if (mz)
    {
      if ( mz>0 )
        DspNodeMom_1 (p, mz);
      else
        DspNodeMom_2 (p, mz);
    }

  }
}


/*                                                              **
**  This function displays the positive horizontal nodal force  **
**                                                              */
static void DspNodeHor_1 (

Tpoint *p,   /* Point location where the force will be displayed */
double px)   /* Horizontal force value */

{
  static Tpoint linep1[2], linep2[3];  /* aux. variables to */
                                       /* draw the force    */

  /* build the force */

  linep1[0].x = ( p->x ) - ( size_n );
  linep1[0].y = ( p->y );
  linep1[1].x = ( p->x ) - ( size_n * 0.2 );
  linep1[1].y = ( p->y );

  linep2[0].x = linep1[1].x - ( size_n * 0.20 );
  linep2[0].y = linep1[1].y + ( size_n * 0.10 );
  linep2[1].x = linep1[1].x;
  linep2[1].y = linep1[1].y;
  linep2[2].x = linep1[1].x - ( size_n * 0.20 );
  linep2[2].y = linep1[1].y - ( size_n * 0.10 );

  /* draw the force */

  GraPolyLine ( 2, linep1 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, linep2 );

 /* display load value */
 if( VisLoadVal == 1 )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, Q2EDNumberFormat(GlobalUnits.ForceForm), 
                   Q2EDConvFromRefUnit(GlobalUnits.Force, px) );
  //FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, UnitsNames[GlobalUnits.Force] );

  shift = 0.05 * size_n;
  pos.x = p->x - ( size_n * 0.50 ) - shift;
  pos.y = p->y - shift;

  charup.x = 0.0;
  charup.y = 1.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_NORTH_EAST );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                              **
**  This function displays the negative horizontal nodal force  **
**                                                              */
static void DspNodeHor_2 (

Tpoint *p,   /* Point location where the force will be displayed */
double px)   /* Horizontal force value */

{
  static Tpoint linep1[2], linep2[3];  /* aux. variables to */
                                       /* draw the force    */
  /* build the force */

  linep1[0].x = ( p->x ) + ( size_n );
  linep1[0].y = ( p->y );
  linep1[1].x = ( p->x ) + ( size_n * 0.2 );
  linep1[1].y = ( p->y );

  linep2[0].x = linep1[1].x + ( size_n * 0.20 );
  linep2[0].y = linep1[1].y + ( size_n * 0.10 );
  linep2[1].x = linep1[1].x;
  linep2[1].y = linep1[1].y;
  linep2[2].x = linep1[1].x + ( size_n * 0.20 );
  linep2[2].y = linep1[1].y - ( size_n * 0.10 );

  /* draw the force */

  GraPolyLine ( 2, linep1 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, linep2 );

 /* display load value */
 if( VisLoadVal == 1 )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, Q2EDNumberFormat(GlobalUnits.ForceForm), 
                   Q2EDConvFromRefUnit(GlobalUnits.Force, fabs(px)) );
  //FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, UnitsNames[GlobalUnits.Force] );

  shift = 0.05 * size_n;
  pos.x = p->x + ( size_n * 0.50 ) + shift;
  pos.y = p->y - shift;

  charup.x = 0.0;
  charup.y = 1.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_NORTH_WEST );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                            **
**  This function displays the positive vertical nodal force  **
**                                                            */
static void DspNodeVert_1 (

Tpoint *p,   /* Point location where the force will be displayed */
double py)   /* Vertical force value */

{
  static Tpoint linep1[2], linep2[3];  /* aux. variables to */
                                       /* draw the force    */
  /* build the force */

  linep1[0].x = ( p->x );
  linep1[0].y = ( p->y ) - ( size_n );
  linep1[1].x = ( p->x );
  linep1[1].y = ( p->y ) - ( size_n * 0.2 );

  linep2[0].x = linep1[1].x - ( size_n * 0.10 );
  linep2[0].y = linep1[1].y - ( size_n * 0.20 );
  linep2[1].x = linep1[1].x;
  linep2[1].y = linep1[1].y;
  linep2[2].x = linep1[1].x + ( size_n * 0.10 );
  linep2[2].y = linep1[1].y - ( size_n * 0.20 );

  /* draw the force */

  GraPolyLine ( 2, linep1 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, linep2 );

 /* display load value */
 if( VisLoadVal == 1 )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, Q2EDNumberFormat(GlobalUnits.ForceForm), 
                   Q2EDConvFromRefUnit(GlobalUnits.Force, py) );
  //FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, UnitsNames[GlobalUnits.Force] );

  shift = 0.15 * size_n;
  pos.x = p->x - shift;
  pos.y = p->y - ( size_n * 0.50 ) - shift;

  charup.x = -1.0;
  charup.y =  0.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_BASE_RIGHT );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                            **
**  This function displays the negative vertical nodal force  **
**                                                            */
static void DspNodeVert_2 (

Tpoint *p,   /* Point location where the force will be displayed */
double py)   /* Vertical force value */

{
  static Tpoint linep1[2], linep2[3];  /* aux. variables to */
                                       /* draw the force    */
  /* build the force */

  linep1[0].x = ( p->x );
  linep1[0].y = ( p->y ) + ( size_n );
  linep1[1].x = ( p->x );
  linep1[1].y = ( p->y ) + ( size_n * 0.2 );

  linep2[0].x = linep1[1].x - ( size_n * 0.10 );
  linep2[0].y = linep1[1].y + ( size_n * 0.20 );
  linep2[1].x = linep1[1].x;
  linep2[1].y = linep1[1].y;
  linep2[2].x = linep1[1].x + ( size_n * 0.10 );
  linep2[2].y = linep1[1].y + ( size_n * 0.20 );

  /* draw the force */

  GraPolyLine ( 2, linep1 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, linep2 );

 /* display load value */
 if( VisLoadVal == 1 )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, Q2EDNumberFormat(GlobalUnits.ForceForm), 
                   Q2EDConvFromRefUnit(GlobalUnits.Force, fabs(py)) );
  //FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, UnitsNames[GlobalUnits.Force] );

  shift = 0.15 * size_n;
  pos.x = p->x - shift;
  pos.y = p->y + ( size_n * 0.50 ) + shift;

  charup.x = -1.0;
  charup.y =  0.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_BASE_LEFT );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                    **
**  This function displays the positive nodal moment  **
**                                                    */
static void DspNodeMom_1 (

Tpoint *p,   /* Point location where the moment will be displayed */
double mz)   /* Moment value */

{
  static Tpoint tip, arrow[3];

  tip.x = p->x - size_m;
  tip.y = p->y;

  arrow[0].x = tip.x - ( size_n * 0.10 );
  arrow[0].y = tip.y + ( size_n * 0.20 );
  arrow[1].x = tip.x;
  arrow[1].y = tip.y;
  arrow[2].x = tip.x + ( size_n * 0.10 );
  arrow[2].y = tip.y + ( size_n * 0.20 );

  DspUtlRotationPoints( -PI/12.0, &tip, arrow, 3 );

  /* draw the moment */

  GraArc ( p, size_m, 0.0, 180.0 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, arrow );

 /* display load value */
 if( VisLoadVal == 1 )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, Q2EDNumberFormat(GlobalUnits.MomentForm), 
                   Q2EDConvFromRefUnit(GlobalUnits.Moment, mz) );
  //FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, UnitsNames[GlobalUnits.Moment] );

  shift = 0.10 * size_m;
  pos.x = p->x + (0.866 * size_m) + shift;
  pos.y = p->y + (0.500 * size_m) + shift;

  charup.x = 0.0;
  charup.y = 1.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_BASE_LEFT );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                    **
**  This function displays the negative nodal moment  **
**                                                    */
static void DspNodeMom_2 (

Tpoint *p,   /* Point location where the moment will be displayed */
double mz)   /* Moment value */

{
  static Tpoint tip, arrow[3];

  tip.x = p->x + size_m;
  tip.y = p->y;

  arrow[0].x = tip.x + ( size_n * 0.10 );
  arrow[0].y = tip.y + ( size_n * 0.20 );
  arrow[1].x = tip.x;
  arrow[1].y = tip.y;
  arrow[2].x = tip.x - ( size_n * 0.10 );
  arrow[2].y = tip.y + ( size_n * 0.20 );

  DspUtlRotationPoints( PI/12.0, &tip, arrow, 3 );

  /* draw the moment */

  GraArc ( p, size_m, 0.0, 180.0 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, arrow );

 /* display load value */
 if( VisLoadVal == 1 )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, Q2EDNumberFormat(GlobalUnits.MomentForm), 
                   Q2EDConvFromRefUnit(GlobalUnits.Moment, fabs(mz)) );
  //FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, UnitsNames[GlobalUnits.Moment] );

  shift = 0.10 * size_m;
  pos.x = p->x - (0.866 * size_m) - shift;
  pos.y = p->y + (0.500 * size_m) + shift;

  charup.x = 0.0;
  charup.y = 1.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_BASE_RIGHT );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}



/*                                                       **
**  This function displays the uniform and linear loads  **
**                                                       */

void DspConstLoadMember (

 int      npts,   /* Number of points that define the curve         */
 Tpoint   *pts,    /* points that define the curve                   */
 Tsystem  dir,     /* Variable that defines if the direction         */
                   /* system of the load is local or global          */
 double   qx,     /* The horizontal load value at the initial point */
 double   qy,     /* The vertical load value at the initial point   */
 double   L,      /*  */
 int      colour)  /* Colour's forces draw                           */

{
  double      r, factor, cos_a, sin_a, narrow = dsp_sizel*0.5;
  int         i, j, n_spaces;
  Tpoint     *newpts = (Tpoint *) calloc (npts, sizeof (Tpoint));
  Tpoint      seta2[NNarrowPts], seta3[NNarrowPts], pt_tx = {0.0, 0.0};

  if (!qx && !qy)
  {
    free (newpts);
    return;
  }

  r = sqrt (qx*qx + qy*qy);

  if (r == 0.0)
  {
    free (newpts);
    return;
  }

  factor = narrow / r;
  cos_a = qx / r;
  sin_a = qy / r;
  n_spaces = (int) (L /  (dsp_sizel*0.4));

  // local narrow
  for (i = 0; i < NNarrowPts; i++)
  {
    seta2[i].x = cos_a * Narrow1[i].x * narrow - sin_a * Narrow1[i].y * narrow;
    seta2[i].y = sin_a * Narrow1[i].x * narrow + cos_a * Narrow1[i].y * narrow;
  }
  

  size_txt = dsp_sizetxt;
  GraSetTextHeight( size_txt );

  GraSetLineColor (colour);
  GraSetTextColor (colour);

  // internal narrows
  if (n_spaces > 1)
  {
    double curr_l = 0.0, step_l = 0.0, space_narrow = L / (n_spaces*1.0);
    double delta, dx, dy;
    int    curr_narrow = 1;
   
    for (i = 0; i < npts-1; i++)
    {
      step_l = sqrt (((pts[i+1].x-pts[i].x) * (pts[i+1].x-pts[i].x)) + 
                     ((pts[i+1].y-pts[i].y) * (pts[i+1].y-pts[i].y)));
      while (((curr_narrow*space_narrow) > curr_l) &&
             ((curr_narrow*space_narrow) <= (curr_l + step_l)) )
      {
        delta = (curr_narrow*space_narrow - curr_l) / step_l;
        dx = pts[i].x + (pts[i+1].x - pts[i].x) * delta;
        dy = pts[i].y + (pts[i+1].y - pts[i].y) * delta;

        for (j = 0; j < NNarrowPts; j++)
        {
          seta3[j].x = dx + seta2[j].x;
          seta3[j].y = dy + seta2[j].y;
        }
        GraPolyLine (NNarrowPts, seta3);
        curr_narrow++;
      }
 
      if ((curr_l < L/2.0) && ((curr_l+step_l) > L/2.0))
      {
        delta = (L/2.0 - curr_l) / step_l;
        dx = pts[i].x + (pts[i+1].x - pts[i].x) * delta;
        dy = pts[i].y + (pts[i+1].y - pts[i].y) * delta;
        pt_tx.x = dx + qx * factor;
        pt_tx.y = dy + qy * factor;
      }
 
      curr_l += step_l;
    }
  }

  // i and j points
  for (j = 0; j < NNarrowPts; j++)
  {
    seta3[j].x = pts[0].x + seta2[j].x;
    seta3[j].y = pts[0].y + seta2[j].y;
  }
  GraPolyLine (NNarrowPts, seta3);
  for (j = 0; j < NNarrowPts; j++)
  {
    seta3[j].x = pts[npts-1].x + seta2[j].x;
    seta3[j].y = pts[npts-1].y + seta2[j].y;
  }
  GraPolyLine (NNarrowPts, seta3);

  // load line
  for (i = 0; i < npts; i++)
  {
    newpts[i].x = pts[i].x + qx * factor;
    newpts[i].y = pts[i].y + qy * factor;
  }
  GraPolyLine (npts, newpts);



 /* display load value */
 if( 1 /* VisLoadVal == 1 */ )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, Q2EDNumberFormat(GlobalUnits.DistribuitedLoadForm), 
                   Q2EDConvFromRefUnit(GlobalUnits.DistribuitedLoad, fabs(r)) );
  //FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, UnitsNames[GlobalUnits.DistribuitedLoad] );

  shift = 0.10 * size_m;
  pos.x = pt_tx.x;
  pos.y = pt_tx.y;

  charup.x = 0.0;
  charup.y = 1.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_BASE_CENTER );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }

  free (newpts);

}


#if 0

/*                                                       **
**  This function displays the uniform and linear loads  **
**  defined in the local system of a member              **
**                                                       */

static void DspLoadMembLocal (

 Tpoint   *pi,     /* Points that define the begin                   */
 double   qxi,     /* The horizontal load value at the initial point */
 double   qyi,     /* The vertical load value at the initial point   */
 double   qxj,     /* The horizontal load value at the final point   */
 double   qyj,     /* The vertical load value at the final point     */
 double   dx,      /* Horizontal and vertical components             */
 double   dy,      /* of the length of the loaded member             */
 double   l)       /* Length of the loaded member                    */

{
  double   coefi;  /* Coefficients that determinates the relations with the  */
  double   coefj;  /* transversal load sizes at the initial and final points */
  int      sizelold_reduced = 0;

  /* Check to see whether there is longitudinal load */
  /* component (in LS).  If there is not, reduce its */
  /* reference size so that the transversal component*/
  /* will be displayed closer to the member axis.    */
  /* Also check for longitudinal and transversal load*/
  /* displayed on opposite fibers of the member.  In */
  /* this case, also reduce reference size of long.  */
  /* load.                                           */

  if ( !qxi && !qxj )
  {
    size_lold /= 3.0;
    sizelold_reduced = 1;
  }
  else
  {
    if ( (qxi>=0.0) && (qxj>=0.0) && 
         (qyi<=0.0) && (qyj<=0.0) )
    {
      size_lold /= 3.0;
      sizelold_reduced = 1;
    }
    if ( (qxi<=0.0) && (qxj<=0.0) && 
         (qyi>=0.0) && (qyj>=0.0) )
    {
      size_lold /= 3.0;
      sizelold_reduced = 1;
    }
  }


  /* if exists transversal loads components (in LS), and  */
  /* according to the signals and the relation with them  */
  /* call the proper function to display these components */

  if ( qyi || qyj )
  {
    if ( fabs (qyi - qyj) < TOLELL )
    {
    /*  for uniform loads  */

      coefi = coefj = 1.0;
      if ( qyi>0 )
      {
        DspMemberTrans_1 ( pi, dx, dy, l, coefi, coefj );
        if( VisLoadVal == ON )
          DspMemberTransVal_1( pi, dx, dy, l, coefi, MEMBER_CTR, qyi );
      }
      else
      {
        DspMemberTrans_2 ( pi, dx, dy, l, coefi, coefj );
        if( VisLoadVal == ON )
          DspMemberTransVal_2( pi, dx, dy, l, coefi, MEMBER_CTR, qyi );
      }
    }
    else
    {
      if ( (qyi>0) && (qyj>0) )
      {
      /*  for positive trapezoidal loads  */

        if ( qyi>qyj )
        {
          coefi = 1.5;
          coefj = 0.5;
          DspMemberTrans_1 ( pi, dx, dy, l, coefi, coefj );
        }
        else
        {
          coefi = 0.5;
          coefj = 1.5;
          DspMemberTrans_1 ( pi, dx, dy, l, coefi, coefj );
        }
        if( VisLoadVal == ON )
        {
          DspMemberTransVal_1( pi, dx, dy, l, coefi, MEMBER_INI, qyi );
          DspMemberTransVal_1( pi, dx, dy, l, coefj, MEMBER_END, qyj );
        }
      }
      else
      {
        if ( (qyi<0) && (qyj<0) )
        {
          /* for negative trapezoidal loads */

          if ( fabs (qyi) > fabs (qyj) )
          {
            coefi = 1.5;
            coefj = 0.5;
            DspMemberTrans_2 ( pi, dx, dy, l, coefi, coefj );
          }
          else
          {
            coefi = 0.5;
            coefj = 1.5;
            DspMemberTrans_2 ( pi, dx, dy, l, coefi, coefj );
          }
          if( VisLoadVal == ON )
          {
            DspMemberTransVal_2( pi, dx, dy, l, coefi, MEMBER_INI, qyi );
            DspMemberTransVal_2( pi, dx, dy, l, coefj, MEMBER_END, qyj );
          }
        }
	      else
        {
	         /* for triangular loads */

	        if ( !qyj )
	        {
	          coefi = 1.5;
	          coefj = 0.0;
	          if ( qyi>0 )
	          {
	            DspMemberTrans_1 ( pi, dx, dy, l, coefi, coefj );
	            if( VisLoadVal == ON )
	              DspMemberTransVal_1( pi, dx, dy, l, coefi, MEMBER_INI, qyi );
	          }
	          else
            {
	            DspMemberTrans_2 ( pi, dx, dy, l, coefi, coefj );
              if( VisLoadVal == ON )
	              DspMemberTransVal_2( pi, dx, dy, l, coefi, MEMBER_INI, qyi );
            }
	        }
	        else
	        {
            if ( !qyi )
            {
              coefi = 0.0;
	            coefj = 1.5;
	            if ( qyj>0 )
	            {
	              DspMemberTrans_1 ( pi, dx, dy, l, coefi, coefj );
	              if( VisLoadVal == ON )
	                DspMemberTransVal_1( pi, dx, dy, l, coefj, MEMBER_END, qyj );
	            }
	            else
	            {
	              DspMemberTrans_2 ( pi, dx, dy, l, coefi, coefj );
	              if( VisLoadVal == ON )
	              DspMemberTransVal_2( pi, dx, dy, l, coefj, MEMBER_END, qyj );
	            }
            }
	          else
	          {

	            /* all the others cases happen when the transversal */
	            /* components have different signals                */

	            if ( fabs (qyi + qyj) < TOLELL )  /* they have the same */
	            /* absolute value     */
	            {
	              coefi = 1.0;
	              coefj = 1.0;
	              if ( qyi>0 )
	                DspMemberTrans_3 ( pi, dx, dy, l, coefi, coefj );
	              else
	                DspMemberTrans_4 ( pi, dx, dy, l, coefi, coefj );
	            }
	            else
	            {
	              if ( fabs (qyi) > fabs (qyj) )
	              {
	                coefi = 1.4;
	                coefj = 0.7;
	                if ( qyi>0 )
	                  DspMemberTrans_5 ( pi, dx, dy, l, coefi, coefj );
	                else
	                  DspMemberTrans_6 ( pi, dx, dy, l, coefi, coefj );
	              }
	              else
	              {
	                coefi = 0.7;
	                coefj = 1.4;
	                if ( qyi>0 )
	                  DspMemberTrans_7 ( pi, dx, dy, l, coefi, coefj );
	                else
	                  DspMemberTrans_8 ( pi, dx, dy, l, coefi, coefj );
	              }
	            }

	            if( VisLoadVal == ON )
	            {
	              if ( qyi>0 )
	                DspMemberTransVal_1( pi, dx, dy, l, coefi, MEMBER_INI, qyi );
	              else
	                DspMemberTransVal_2( pi, dx, dy, l, coefi, MEMBER_INI, qyi );

	              if ( qyj>0 )
	                DspMemberTransVal_1( pi, dx, dy, l, coefj, MEMBER_END, qyj );
	              else
	                DspMemberTransVal_2( pi, dx, dy, l, coefj, MEMBER_END, qyj );
	            }
	          }
          }
        }
	    }
    }
  }

  if( sizelold_reduced )
   size_lold *= 3.0;

  /* if exists longitudinal load component (in LS), */
  /* and according to the signal call the proper    */
  /* function to display this component             */

  if ( qxi || qxj )
  {
    if ( fabs (qxi - qxj) < TOLELL )
    {
    /*  for uniform loads  */

      if ( qxi>0 )
      {
	DspMemberLong_1 ( pi, dx, dy, l );
        if( VisLoadVal == ON )
         DspMemberLongVal_1( pi, dx, dy, l, MEMBER_CTR, qxi );
      }
      else
      {
	DspMemberLong_2 ( pi, dx, dy, l );
        if( VisLoadVal == ON )
         DspMemberLongVal_2( pi, dx, dy, l, MEMBER_CTR, qxi );
      }
    }
    else
    {
      if ( (qxi>0) && (qxj>0) )
      {
      /*  for positive trapezoidal loads  */

	DspMemberLong_1 ( pi, dx, dy, l );
        if( VisLoadVal == ON )
        {
         DspMemberLongVal_1( pi, dx, dy, l, MEMBER_INI, qxi );
         DspMemberLongVal_1( pi, dx, dy, l, MEMBER_END, qxj );
        }
      }
      else
      {
	if ( (qxi<0) && (qxj<0) )
	{
	/* for negative trapezoidal loads */

	  DspMemberLong_2 ( pi, dx, dy, l );
          if( VisLoadVal == ON )
          {
           DspMemberLongVal_2( pi, dx, dy, l, MEMBER_INI, qxi );
           DspMemberLongVal_2( pi, dx, dy, l, MEMBER_END, qxj );
          }
	}
	else
	{
	/* for triangular loads */

	  if ( !qxj )
	  {
	    if ( qxi>0 )
            {
	      DspMemberLong_1 ( pi, dx, dy, l );
              if( VisLoadVal == ON )
               DspMemberLongVal_1( pi, dx, dy, l, MEMBER_INI, qxi );
            }
	    else
            {
	      DspMemberLong_2 ( pi, dx, dy, l );
              if( VisLoadVal == ON )
               DspMemberLongVal_2( pi, dx, dy, l, MEMBER_INI, qxi );
            }
	  }
	  else
	  {
	    if ( !qxi )
	    {
	      if ( qxj>0 )
              {
		DspMemberLong_1 ( pi, dx, dy, l );
                if( VisLoadVal == ON )
                 DspMemberLongVal_1( pi, dx, dy, l, MEMBER_END, qxj );
              }
	      else
              {
		DspMemberLong_2 ( pi, dx, dy, l );
                if( VisLoadVal == ON )
                 DspMemberLongVal_2( pi, dx, dy, l, MEMBER_END, qxj );
              }
	    }
	    else
	    {
	      double length;
	      Tpoint refpt;

	    /* all the others cases happen when the longitudinal */
	    /* components have different signals                 */

	      if ( fabs (qxi + qxj) < TOLELL )  /* they have the same */
						/* absolute value     */
	      {
		length = l * 0.5;
		if ( qxi>0 )
		  DspMemberLong_1 ( pi, dx, dy, length );
		else
		  DspMemberLong_2 ( pi, dx, dy, length );
 		refpt.x = ( pi->x ) + ( dx * 0.5 );
 		refpt.y = ( pi->y ) + ( dy * 0.5 );
		if ( qxj>0 )
		  DspMemberLong_1 ( &refpt, dx, dy, length );
		else
		  DspMemberLong_2 ( &refpt, dx, dy, length );
	      }
	      else
	      {
		if ( fabs (qxi) > fabs (qxj) )
		{
		  length = l * (2.0/3.0);
		  if ( qxi>0 )
		    DspMemberLong_1 ( pi, dx, dy, length );
		  else
		    DspMemberLong_2 ( pi, dx, dy, length );
 		  refpt.x = ( pi->x ) + ( dx * (2.0/3.0) );
 		  refpt.y = ( pi->y ) + ( dy * (2.0/3.0) );
		  length = l / 3.0;
		  if ( qxj>0 )
		    DspMemberLong_1 ( &refpt, dx, dy, length );
		  else
		    DspMemberLong_2 ( &refpt, dx, dy, length );
		}
		else
		{
		  length = l / 3.0;
		  if ( qxi>0 )
		    DspMemberLong_1 ( pi, dx, dy, length );
		  else
		    DspMemberLong_2 ( pi, dx, dy, length );
 		  refpt.x = ( pi->x ) + ( dx / 3.0 );
 		  refpt.y = ( pi->y ) + ( dy / 3.0 );
		  length = l * (2.0/3.0);
		  if ( qxj>0 )
		    DspMemberLong_1 ( &refpt, dx, dy, length );
		  else
		    DspMemberLong_2 ( &refpt, dx, dy, length );
		}
	      }

              if( VisLoadVal == ON )
              {
	       if ( qxi>0 )
                DspMemberLongVal_1( pi, dx, dy, l, MEMBER_INI, qxi );
               else
                DspMemberLongVal_2( pi, dx, dy, l, MEMBER_INI, qxi );

	       if ( qxj>0 )
                DspMemberLongVal_1( pi, dx, dy, l, MEMBER_END, qxj );
               else
                DspMemberLongVal_2( pi, dx, dy, l, MEMBER_END, qxj );
              }
	    }
	  }
	}
      }
    }
  }
}


/*                                                       **
**  This function displays the uniform and linear loads  **
**  defined in the global system of a member              **
**                                                       */

static void DspLoadMembGlobal (

 Tpoint   *pi,     /* Points that define the begin                   */
 double   qxi,     /* The horizontal load value at the initial point */
 double   qyi,     /* The vertical load value at the initial point   */
 double   qxj,     /* The horizontal load value at the final point   */
 double   qyj,     /* The vertical load value at the final point     */
 double   dx,      /* Horizontal and vertical components             */
 double   dy,      /* of the length of the loaded member             */
 double   l)       /* Length of the loaded member                    */

{
  double   coefi;  /* Coefficients that determinates the relations with the  */
  double   coefj;  /* transversal load sizes at the initial and final points */
  double   qi,qj;  /* Distributed load intensities at the begining and end   */
  double   lxi,lyi;/* Horizontal and vertical unit load direction components */
  double   lxj,lyj;
  double   qli,qlj;/* Longitudinal components of distributed loads           */
  double   qti,qtj;/* Transversal components of distributed loads            */

  /* In the computation of the loat unit vector direction,
     it is assumed that the distributed load at the begining 
     and at the end of the member have the same direction.
     Therefore, the load components at the final point are 
     forced to have the same direction with the given 
     orientation. */

  qi = sqrt ( qxi*qxi + qyi*qyi );
  lxi = qxi / qi;
  lyi = qyi / qi;
  qj = sqrt ( qxj*qxj + qyj*qyj );
  if ( qi > 0.0001 )
  {
   if ( (qxi*qxj + qyi*qyj) < 0.0 ) /* end load have opposite orientation */
   {
    lxj = -lxi;
    lyj = -lyi;
   }
   else                             /* end load have same orientation */
   {
    lxj = lxi;
    lyj = lyi;
   }
   if( fabs(lxj) > fabs(lyj) )
    qyj = (lyj/lxj) * qxj;
   else
    qxj = (lxj/lyj) * qyj;
  }
  else
  {
   qj = sqrt ( qxj*qxj + qyj*qyj );
   if ( qj < 0.0001 )
    return;
   lxj = qxj / qj;
   lyj = qyj / qj;
   lxi = lxj;
   lyi = lyj;
  }

  /* The longitudinal load components are computed taking the dot
     product with the unit member vector direction */

  qli = (dx * qxi + dy * qyi) / l;
  qlj = (dx * qxj + dy * qyj) / l;
  if ( fabs (qli) < TOLELL )
    qli = 0.0;
  if ( fabs (qlj) < TOLELL )
    qlj = 0.0;

  /* The transversal load components are computed taking the dot
     product with the unit normal to the member */

  qti = (dx * qyi - dy * qxi) / l;
  qtj = (dx * qyj - dy * qxj) / l;
  if ( fabs (qti) < TOLELL )
    qti = 0.0;
  if ( fabs (qtj) < TOLELL )
    qtj = 0.0;


  /* if exists tranversal load component            */
  /* (or if load is not almost parallel to member), */
  /* according to the signal, call the proper       */
  /* function to display the load                   */

  if ( ( qti || qtj ) && 
       ( fabs((dx * lyi - dy * lxi) / l) > 0.15 ) ) /* not almost parallel */ 
  {
    if ( fabs( qti - qtj) < TOLELL )
    {
    /*  for uniform loads  */

      coefi = coefj = 1.0;
      if ( qti>0 )
      {
	DspMemberGlobal_1 ( pi, dx, dy, l, lxi, lyi, coefi, coefj );
        if( VisLoadVal == ON )
	 DspMemberGlobalVal_1( pi, dx, dy, l, lxi, lyi, coefi, MEMBER_CTR, qi );
      }
      else
      {
	DspMemberGlobal_2 ( pi, dx, dy, l, lxi, lyi, coefi, coefj );
        if( VisLoadVal == ON )
	 DspMemberGlobalVal_2( pi, dx, dy, l, lxi, lyi, coefi, MEMBER_CTR, qi );
      }
    }
    else
    {
      if ( (qti>0) && (qtj>0) )
      {
      /*  for positive trapezoidal loads  */

	if ( fabs (qti) > fabs (qtj) )
	{
	  coefi = 1.5;
	  coefj = 0.5;
	  DspMemberGlobal_1 ( pi, dx, dy, l, lxi, lyi, coefi, coefj );
	}
	else
	{
	  coefi = 0.5;
	  coefj = 1.5;
	  DspMemberGlobal_1 ( pi, dx, dy, l, lxi, lyi, coefi, coefj );
	}
        if( VisLoadVal == ON )
        {
	 DspMemberGlobalVal_1( pi, dx, dy, l, lxi, lyi, coefi, MEMBER_INI, qi );
	 DspMemberGlobalVal_1( pi, dx, dy, l, lxi, lyi, coefj, MEMBER_END, qj );
        }
      }
      else
      {
	if ( (qti<0) && (qtj<0) )
	{
	/* for negative trapezoidal loads */

	  if ( fabs (qti) > fabs (qtj) )
	  {
	    coefi = 1.5;
	    coefj = 0.5;
	    DspMemberGlobal_2 ( pi, dx, dy, l, lxi, lyi, coefi, coefj );
	  }
	  else
	  {
	    coefi = 0.5;
	    coefj = 1.5;
	    DspMemberGlobal_2 ( pi, dx, dy, l, lxi, lyi, coefi, coefj );
	  }
          if( VisLoadVal == ON )
          {
	   DspMemberGlobalVal_2(pi, dx, dy, l, lxi, lyi, coefi, MEMBER_INI, qi);
	   DspMemberGlobalVal_2(pi, dx, dy, l, lxi, lyi, coefj, MEMBER_END, qj);
          }
	}
	else
	{
	/* for triangular transversal loads */

	  if ( !qtj )
	  {
	    coefi = 1.5;
	    if ( !qj )
	      coefj = 0.0;
	    else
	      coefj = 0.5;
	    if ( qti>0 )
            {
	      DspMemberGlobal_1 ( pi, dx, dy, l, lxi, lyi, coefi, coefj );
              if( VisLoadVal == ON )
	       DspMemberGlobalVal_1(pi,dx,dy,l,lxi,lyi,coefi,MEMBER_INI,qi);
            }
	    else
            {
	      DspMemberGlobal_2 ( pi, dx, dy, l, lxi, lyi, coefi, coefj );
              if( VisLoadVal == ON )
	       DspMemberGlobalVal_2(pi,dx,dy,l,lxi,lyi,coefi,MEMBER_INI,qi);
            }
	  }
	  else
	  {
	    if ( !qti )
	    {
	      if ( !qi )
		coefi = 0.0;
	      else
		coefi = 0.5;
	      coefj = 1.5;
	      if ( qtj>0 )
              {
		DspMemberGlobal_1 ( pi, dx, dy, l, lxi, lyi, coefi, coefj );
                if( VisLoadVal == ON )
	         DspMemberGlobalVal_1(pi,dx,dy,l,lxi,lyi,coefj,MEMBER_END,qj);
              }
	      else
              {
		DspMemberGlobal_2 ( pi, dx, dy, l, lxi, lyi, coefi, coefj );
                if( VisLoadVal == ON )
	         DspMemberGlobalVal_2(pi,dx,dy,l,lxi,lyi,coefj,MEMBER_END,qj);
              }
	    }
	    else
	    {
	      double length;
	      Tpoint refpt;
	      double coefaux = 0.0;

	    /* all the others cases happen when the transversal */
	    /* components have different signals                */

	      if ( fabs (qti + qtj) < TOLELL )  /* they have the same */
					        /* absolute value     */
	      {
		coefi = 1.0;
		coefj = 1.0;
		length = l * 0.5;

		if ( qti>0 )
                  DspMemberGlobal_1 ( pi, dx, dy, length, lxi, lyi, 
                                      coefi, coefaux );
		else
                  DspMemberGlobal_2 ( pi, dx, dy, length, lxi, lyi, 
                                      coefi, coefaux );
 		refpt.x = ( pi->x ) + ( dx * 0.5 );
 		refpt.y = ( pi->y ) + ( dy * 0.5 );
		if ( qtj>0 )
                  DspMemberGlobal_1 ( &refpt, dx, dy, length, lxj, lyj, 
                                      coefaux, coefj );
		else
                  DspMemberGlobal_2 ( &refpt, dx, dy, length, lxj, lyj, 
                                      coefaux, coefj );
	      }
	      else
	      {
		if ( fabs (qti) > fabs (qtj) )
		{
		  coefi = 1.4;
		  coefj = 0.7;
		  length = l * (2.0/3.0);
		  if ( qti>0 )
                    DspMemberGlobal_1 ( pi, dx, dy, length, lxi, lyi, 
                                        coefi, coefaux );
		  else
                    DspMemberGlobal_2 ( pi, dx, dy, length, lxi, lyi, 
                                        coefi, coefaux );
 		  refpt.x = ( pi->x ) + ( dx * (2.0/3.0) );
 		  refpt.y = ( pi->y ) + ( dy * (2.0/3.0) );
		  length = l / 3.0;
		  if ( qtj>0 )
                    DspMemberGlobal_1 ( &refpt, dx, dy, length, lxj, lyj, 
                                        coefaux, coefj );
		  else
                    DspMemberGlobal_2 ( &refpt, dx, dy, length, lxj, lyj, 
                                        coefaux, coefj );
		}
		else
		{
		  coefi = 0.7;
		  coefj = 1.4;
		  length = l / 3.0;
		  if ( qti>0 )
                    DspMemberGlobal_1 ( pi, dx, dy, length, lxi, lyi, 
                                        coefi, coefaux );
		  else
                    DspMemberGlobal_2 ( pi, dx, dy, length, lxi, lyi, 
                                        coefi, coefaux );
 		  refpt.x = ( pi->x ) + ( dx / 3.0 );
 		  refpt.y = ( pi->y ) + ( dy / 3.0 );
		  length = l * (2.0/3.0);
		  if ( qtj>0 )
                    DspMemberGlobal_1 ( &refpt, dx, dy, length, lxj, lyj, 
                                        coefaux, coefj );
		  else
                    DspMemberGlobal_2 ( &refpt, dx, dy, length, lxj, lyj, 
                                        coefaux, coefj );
		}
	      }

              if( VisLoadVal == ON )
              {
	       if ( qti>0 )
	        DspMemberGlobalVal_1(pi,dx,dy,l,lxi,lyi,coefi,MEMBER_INI,qi);
	       else
	        DspMemberGlobalVal_2(pi,dx,dy,l,lxi,lyi,coefi,MEMBER_INI,qi);

	       if ( qtj>0 )
	        DspMemberGlobalVal_1(pi,dx,dy,l,-lxi,-lyi,coefj,MEMBER_END,qj);
	       else
	        DspMemberGlobalVal_2(pi,dx,dy,l,-lxi,-lyi,coefj,MEMBER_END,qj);
              }
	    }
	  }
	}
      }
    }
  }
  else if ( qli || qlj )
  {

  /* if exists pure longitudinal load components,   */
  /* according to the signal, call the proper       */
  /* function to display the load                   */

    if ( fabs (qli - qlj) < TOLELL )
    {
    /*  for uniform loads  */

      if ( qli>0 )
      {
	DspMemberLong_1 ( pi, dx, dy, l );
        if( VisLoadVal == ON )
         DspMemberLongVal_1( pi, dx, dy, l, MEMBER_CTR, qi );
      }
      else
      {
	DspMemberLong_2 ( pi, dx, dy, l );
        if( VisLoadVal == ON )
         DspMemberLongVal_2( pi, dx, dy, l, MEMBER_CTR, qi );
      }
    }
    else
    {
      if ( (qli>0) && (qlj>0) )
      {
      /*  for positive trapezoidal loads  */

	DspMemberLong_1 ( pi, dx, dy, l );
        if( VisLoadVal == ON )
        {
         DspMemberLongVal_1( pi, dx, dy, l, MEMBER_INI, qi );
         DspMemberLongVal_1( pi, dx, dy, l, MEMBER_END, qj );
        }
      }
      else
      {
	if ( (qli<0) && (qlj<0) )
	{
	/* for negative trapezoidal loads */

	  DspMemberLong_2 ( pi, dx, dy, l );
          if( VisLoadVal == ON )
          {
           DspMemberLongVal_2( pi, dx, dy, l, MEMBER_INI, qi );
           DspMemberLongVal_2( pi, dx, dy, l, MEMBER_END, qj );
          }
	}
	else
	{
	/* for triangular transversal loads */

	  if ( !qlj )
	  {
	    if ( qli>0 )
            {
	      DspMemberLong_1 ( pi, dx, dy, l );
              if( VisLoadVal == ON )
               DspMemberLongVal_1( pi, dx, dy, l, MEMBER_INI, qi );
            }
	    else
            {
	      DspMemberLong_2 ( pi, dx, dy, l );
              if( VisLoadVal == ON )
               DspMemberLongVal_2( pi, dx, dy, l, MEMBER_INI, qi );
            }
	  }
	  else
	  {
	    if ( !qli )
	    {
	      if ( qlj>0 )
              {
		DspMemberLong_1 ( pi, dx, dy, l );
                if( VisLoadVal == ON )
                 DspMemberLongVal_1( pi, dx, dy, l, MEMBER_END, qj );
              }
	      else
              {
		DspMemberLong_2 ( pi, dx, dy, l );
                if( VisLoadVal == ON )
                 DspMemberLongVal_2( pi, dx, dy, l, MEMBER_END, qj );
              }
	    }
	    else
	    {
	      double length;
	      Tpoint refpt;

	    /* all the others cases happen when the longitudinal */
	    /* components have different signals                 */

	      if ( fabs (qli + qlj) < TOLELL )  /* they have the same */
						/* absolute value     */
	      {
		length = l * 0.5;
		if ( qli>0 )
		  DspMemberLong_1 ( pi, dx, dy, length );
		else
		  DspMemberLong_2 ( pi, dx, dy, length );
 		refpt.x = ( pi->x ) + ( dx * 0.5 );
 		refpt.y = ( pi->y ) + ( dy * 0.5 );
		if ( qlj>0 )
		  DspMemberLong_1 ( &refpt, dx, dy, length );
		else
		  DspMemberLong_2 ( &refpt, dx, dy, length );
	      }
	      else
	      {
		if ( fabs (qli) > fabs (qlj) )
		{
		  length = l * (2.0/3.0);
		  if ( qli>0 )
		    DspMemberLong_1 ( pi, dx, dy, length );
		  else
		    DspMemberLong_2 ( pi, dx, dy, length );
 		  refpt.x = ( pi->x ) + ( dx * (2.0/3.0) );
 		  refpt.y = ( pi->y ) + ( dy * (2.0/3.0) );
		  length = l / 3.0;
		  if ( qlj>0 )
		    DspMemberLong_1 ( &refpt, dx, dy, length );
		  else
		    DspMemberLong_2 ( &refpt, dx, dy, length );
		}
		else
		{
		  length = l / 3.0;
		  if ( qli>0 )
		    DspMemberLong_1 ( pi, dx, dy, length );
		  else
		    DspMemberLong_2 ( pi, dx, dy, length );
 		  refpt.x = ( pi->x ) + ( dx / 3.0 );
 		  refpt.y = ( pi->y ) + ( dy / 3.0 );
		  length = l * (2.0/3.0);
		  if ( qlj>0 )
		    DspMemberLong_1 ( &refpt, dx, dy, length );
		  else
		    DspMemberLong_2 ( &refpt, dx, dy, length );
		}
	      }

              if( VisLoadVal == ON )
              {
	       if ( qli>0 )
                DspMemberLongVal_1( pi, dx, dy, l, MEMBER_INI, qi );
               else
                DspMemberLongVal_2( pi, dx, dy, l, MEMBER_INI, qi );

	       if ( qlj>0 )
                DspMemberLongVal_1( pi, dx, dy, l, MEMBER_END, qj );
               else
                DspMemberLongVal_2( pi, dx, dy, l, MEMBER_END, qj );
              }
	    }
	  }
	}
      }
    }
  }
}


/*                                       **
**  This function displays the positive  **
**  longitudinal component of the load   **
**                                       */
static void DspMemberLong_1 (

 Tpoint *pi, /* Point that defines the begin of the load */
 double dx,  /* Horizontal and vertical components */
 double dy,  /* of the length of the loaded member */
 double l )  /* Length of the loaded member        */

{
  /* Auxiliar variables */

  int i;
  double dl;
  int    nseg;
  Tpoint line1[2], line2[3];
  double begin;


  /* This function will display many forces in longitudinal direction. */
  /* For each force it's necessary a space to draw it.                 */

  /* This is an adjustment with this space and the length of the member */

  dl = size_lold;              /* space to draw the force */
  nseg = (int)(l / dl);
  dl = l / (double)nseg;

  begin = 0.0;

  for ( i=0; i<nseg; i++ )
  {
    /* build each force */

    line1[0].x = begin;
    line1[0].y = - dl * 0.5;
    line1[1].x = begin + ( dl * 0.75 );
    line1[1].y = line1[0].y;

    line2[0].x = line1[1].x - ( dl * 0.15 );
    line2[0].y = line1[1].y + ( dl * 0.15 );
    line2[1].x = line1[1].x;
    line2[1].y = line1[1].y;
    line2[2].x = line1[1].x - ( dl * 0.15 );
    line2[2].y = line1[1].y - ( dl * 0.15 );

    /* change to global system */

    DspUtlChangeSystemLG ( dx, dy, pi, line1, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, line2, 3 );

    /* draw each force */

    GraPolyLine ( 2, line1 );
    GraPolyLine ( 3, line2 );

    /* adjust the position to draw the force */

    begin += dl;
  }
}


/*                                       **
**  This function displays the negative  **
**  longitudinal component of the load   **
**                                       */
static void DspMemberLong_2 (

 Tpoint *pi, /* Point that defines the begin of the load */
 double dx,  /* Horizontal and vertical components       */
 double dy,  /* of the length of the loaded member       */
 double l )  /* Length of the loaded member              */

{
  /* Auxiliar variables */

  int i;
  double dl;
  int    nseg;
  Tpoint line1[2], line2[3];
  double begin;


  /* This function will display many forces in longitudinal direction. */
  /* For each force it's necessary a space to draw it.                 */

  /* This is an adjustment with this space and the length of the member */

  dl = size_lold;              /* space to draw the force        */
  nseg = (int)(l / dl);
  dl = l / (double)nseg;

  begin = l;
  
  for ( i=0; i<nseg; i++ )
  {
    /* build each force */

    line1[0].x = begin;
    line1[0].y = dl * 0.5;
    line1[1].x = begin - ( dl * 0.75 );
    line1[1].y = line1[0].y;

    line2[0].x = line1[1].x + ( dl * 0.15 );
    line2[0].y = line1[1].y + ( dl * 0.15 );
    line2[1].x = line1[1].x;
    line2[1].y = line1[1].y;
    line2[2].x = line1[1].x + ( dl * 0.15 );
    line2[2].y = line1[1].y - ( dl * 0.15 );

    /* change to global system */

    DspUtlChangeSystemLG ( dx, dy, pi, line1, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, line2, 3 );

    /* draw each force */

    
    GraPolyLine ( 2, line1 );
    GraPolyLine ( 3, line2 );

    /* adjust the position to draw the force */

    begin -= dl;
  }
}


/*                                       **
**  This function displays the positive  **
**  longitudinal component value of the  **
**  member load                          **
**                                       */
static void DspMemberLongVal_1 (

 Tpoint *pi, /* Point that defines the begin of the load */
 double dx,  /* Horizontal and vertical components */
 double dy,  /* of the length of the loaded member */
 double len, /* Length of the loaded member        */
 int    pos, /* code for member position (ini, ctr, end) */
 double px ) /* longitudinal load value */

{
 Tpoint charup;
 Tpoint p;
 double locx;
 double locy;
 double shift;
 int    align;

 sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.dist_load),
                  FtoolConvFromRefUnit(Ftool.unt.dist_load, px) );
 FtoolShrinkExp( dvalue );
 sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.dist_load] );

 locx = 0.1 * size_lold;
 locy = 0.7 * size_lold;
 shift = 0.15 * size_txt;

 switch( pos )
 {
  case MEMBER_INI:
   p.x = locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_WEST;
    p.y = - locy - shift;
   }
   else
   {
    align = GRA_SOUTH_EAST;
    p.y = - locy - shift;
   }
   break;
  default:
  case MEMBER_CTR:
   p.x = (len*0.5) + locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_WEST;
    p.y = - locy - shift;
   }
   else
   {
    align = GRA_SOUTH_EAST;
    p.y = - locy - shift;
   }
   break;
  case MEMBER_END:
   p.x = len - locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_EAST;
    p.y = - locy - shift;
   }
   else
   {
    align = GRA_SOUTH_WEST;
    p.y = - locy - shift;
   }
   break;
 }
 DspUtlChangeSystemLG( dx, dy, pi, &p, 1 );

 if( DspUtlDefOrientation( dx, dy ) )
 {
  charup.x = -dy;
  charup.y = dx;
 }
 else
 {
  charup.x = dy;
  charup.y = -dx;
 }
 GraSetTextCharUp( charup.x, charup.y );

 GraSetTextAlign( align );
 GraBackOpacity( GRA_OPAQUE );
 GraText( &p, dtext );
 GraBackOpacity( GRA_TRANSPARENT );
}


/*                                       **
**  This function displays the negative  **
**  longitudinal component value of the  **
**  member load                          **
**                                       */
static void DspMemberLongVal_2 (

 Tpoint *pi, /* Point that defines the begin of the load */
 double dx,  /* Horizontal and vertical components */
 double dy,  /* of the length of the loaded member */
 double len, /* Length of the loaded member        */
 int    pos, /* code for member position (ini, ctr, end) */
 double px ) /* longitudinal load value */

{
 Tpoint charup;
 Tpoint p;
 double locx;
 double locy;
 double shift;
 int    align;

 sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.dist_load),
                  FtoolConvFromRefUnit(Ftool.unt.dist_load, fabs(px)) );
 FtoolShrinkExp( dvalue );
 sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.dist_load] );

 locx = 0.1 * size_lold;
 locy = 0.7 * size_lold;
 shift = 0.15 * size_txt;

 switch( pos )
 {
  case MEMBER_INI:
   p.x = locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_WEST;
    p.y = locy + shift;
   }
   else
   {
    align = GRA_NORTH_EAST;
    p.y = locy + shift;
   }
   break;
  default:
  case MEMBER_CTR:
   p.x = (len*0.5) + locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_WEST;
    p.y = locy + shift;
   }
   else
   {
    align = GRA_NORTH_EAST;
    p.y = locy + shift;
   }
   break;
  case MEMBER_END:
   p.x = len - locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_EAST;
    p.y = locy + shift;
   }
   else
   {
    align = GRA_NORTH_WEST;
    p.y = locy + shift;
   }
   break;
 }
 DspUtlChangeSystemLG( dx, dy, pi, &p, 1 );

 if( DspUtlDefOrientation( dx, dy ) )
 {
  charup.x = -dy;
  charup.y = dx;
 }
 else
 {
  charup.x = dy;
  charup.y = -dx;
 }
 GraSetTextCharUp( charup.x, charup.y );

 GraSetTextAlign( align );
 GraBackOpacity( GRA_OPAQUE );
 GraText( &p, dtext );
 GraBackOpacity( GRA_TRANSPARENT );
}


/*                                       **
**  This function displays the positive  **
**  transversal component of the load    **
**                                       */
static void DspMemberTrans_1 (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the loaded member */
 double     l,  /* Length of the loaded member        */
 double coefi,  /* Coefficients that determinates the relations with the  */
 double coefj)  /* transversal load sizes at the initial and final points */

{
  /* Auxiliar variables */

  int i;
  double dl;
  int    nseg;
  Tpoint underline[2], line1[2], line2[3];
  double begin, underlimit, limit;


  /* This function will display many forces in transversal direction. */
  /* Between each force it's necessary to define a space.             */

  /* This is an adjustment with this space and the length of the member */

  dl = size_trld * 0.5;  /* space to draw the force */
  nseg = (int)(l / dl);
  dl = l / (double)nseg;

  /* build and draw the "underline" of the load (positive in LS) */

  underline[0].x = 0.0;
  underline[0].y = - ( (coefi * size_trld) + size_lold );
  underline[1].x = l;
  underline[1].y = - ( (coefj * size_trld) + size_lold );

  DspUtlChangeSystemLG ( dx, dy, pi, underline, 2 );

  GraPolyLine ( 2, underline );

  /* Underlimit and limit are limit sizes to draw the forces */

  if (!coefi)
  {
    begin = l;
    underlimit = - ( (coefj * size_trld) + size_lold );
  }
  else
  {
    begin = 0.0;
    underlimit = - ( (coefi * size_trld) + size_lold );
  }
  limit = - ( (0.2 * size_trld) + size_lold );


  for ( i=0; (i<=nseg) && (underlimit < limit); i++ )
  {
    /* build each force */

    line1[0].x = begin;
    line1[0].y = underlimit;
    line1[1].x = begin;
    line1[1].y = - size_lold;

    line2[0].x = line1[1].x - ( size_trld * 0.15 );
    line2[0].y = line1[1].y - ( size_trld * 0.15 );
    line2[1].x = line1[1].x;
    line2[1].y = line1[1].y;
    line2[2].x = line1[1].x + ( size_trld * 0.15 );
    line2[2].y = line1[1].y - ( size_trld * 0.15 );

    /* change to global system */

    DspUtlChangeSystemLG ( dx, dy, pi, line1, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, line2, 3 );

    /* draw each force */

    GraPolyLine ( 2, line1 );
    GraPolyLine ( 3, line2 );

    /* adjust the position to draw the force */

    if (!coefi)
    {
      begin -= dl;
      underlimit -= ( ( dl * ( coefi - coefj ) * size_trld ) / l );
    }
    else
    {
      begin += dl;
      underlimit += ( ( dl * ( coefi - coefj ) * size_trld ) / l );
    }
  }
}


/*                                       **
**  This function displays the negative  **
**  transversal component of the load    **
**                                       */
static void DspMemberTrans_2 (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the loaded member */
 double     l,  /* Length of the loaded member        */
 double coefi,  /* Coefficients that determinates the relations with the  */
 double coefj)  /* transversal load sizes at the initial and final points */

{
  /* Auxiliar variables */

  int i;
  double dl;
  int    nseg;
  Tpoint topline[2], line1[2], line2[3];
  double begin, toplimit, limit;


  /* This function will display many forces in transversal direction. */
  /* Between each force it's necessary to define a space.             */

  /* This is an adjustment with this space and the length of the member */

  dl = size_trld * 0.5;  /* space to draw the force */
  nseg = (int)(l / dl);
  dl = l / (double)nseg;

  /* build and draw the "topline" of the load (negative in LS) */

  topline[0].x = 0.0;
  topline[0].y = (coefi * size_trld) + size_lold;
  topline[1].x = l;
  topline[1].y = (coefj * size_trld) + size_lold;

  DspUtlChangeSystemLG ( dx, dy, pi, topline, 2 );

  GraPolyLine ( 2, topline );

  /* Toplimit and limit are limit sizes to draw the forces */

  if (!coefi)
  {
    begin = l;
    toplimit = (coefj * size_trld) + size_lold;
  }
  else
  {
    begin = 0.0;
    toplimit = (coefi * size_trld) + size_lold;
  }
  limit = (0.2 * size_trld) + size_lold;


  for ( i=0; (i<=nseg) && (toplimit > limit); i++ )
  {
    /* build each force */

    line1[0].x = begin;
    line1[0].y = toplimit;
    line1[1].x = begin;
    line1[1].y = size_lold;

    line2[0].x = line1[1].x - ( size_trld * 0.15 );
    line2[0].y = line1[1].y + ( size_trld * 0.15 );
    line2[1].x = line1[1].x;
    line2[1].y = line1[1].y;
    line2[2].x = line1[1].x + ( size_trld * 0.15 );
    line2[2].y = line1[1].y + ( size_trld * 0.15 );

    /* change to global system */

    DspUtlChangeSystemLG ( dx, dy, pi, line1, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, line2, 3 );

    /* draw each force */

    GraPolyLine ( 2, line1 );
    GraPolyLine ( 3, line2 );

    /* adjust the position to draw the force */

    if (!coefi)
    {
      begin -= dl;
      toplimit += ( ( dl * (coefi - coefj) * size_trld ) / l );
    }
    else
    {
      begin += dl;
      toplimit -= ( ( dl * (coefi - coefj) * size_trld ) / l );
    }
  }
}


/*  -------------------------------------------------------------  **
**                                                                 **
**  All the others functions that display transversal components   **
**  of the load are called when these components have different    **
**  signals at the initial and final points.                       **
**  These functions call DspMemberTrans_1 to display the positive  **
**  part and DspMemberTrans_2 to display the negative part.        **
**                                                                 **
**  -------------------------------------------------------------  */

/*                                                                  **
**  If the transversal component of the load in initial point is    **
**  positive and the absolute value is the same of the final point  **
**                                                                  */
static void DspMemberTrans_3 (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the loaded member */
 double     l,  /* Length of the loaded member        */
 double coefi,  /* Coefficients that determinates the relations with the  */
 double coefj)  /* transversal load sizes at the initial and final points */

{
  /* Auxiliar variables */

  double length;
  Tpoint refpt;
  double coefaux = 0.0;

  length = l / 2.0;
  DspMemberTrans_1 ( pi, dx, dy, length, coefi, coefaux );

  refpt.x = ( pi->x ) + ( dx / 2.0 );
  refpt.y = ( pi->y ) + ( dy / 2.0 );
  DspMemberTrans_2 ( &refpt, dx, dy, length, coefaux, coefj );
}


/*                                                                  **
**  If the transversal component of the load in initial point is    **
**  negative and the absolute value is the same of the final point  **
**                                                                  */
static void DspMemberTrans_4 (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the loaded member */
 double     l,  /* Length of the loaded member        */
 double coefi,  /* Coefficients that determinates the relations with the  */
 double coefj)  /* transversal load sizes at the initial and final points */

{
  /* Auxiliar variables */

  double length;
  Tpoint refpt;
  double coefaux = 0.0;

  length = l / 2.0;
  DspMemberTrans_2 ( pi, dx, dy, length, coefi, coefaux );

  refpt.x = ( pi->x ) + ( dx / 2.0 );
  refpt.y = ( pi->y ) + ( dy / 2.0 );
  DspMemberTrans_1 ( &refpt, dx, dy, length, coefaux, coefj );
}


/*                                                                  **
**  If the transversal component of the load in initial point is    **
**  positive and the absolute value is bigger then the final point  **
**                                                                  */
static void DspMemberTrans_5 (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the loaded member */
 double     l,  /* Length of the loaded member        */
 double coefi,  /* Coefficients that determinates the relations with the  */
 double coefj)  /* transversal load sizes at the initial and final points */

{
  /* Auxiliar variables */

  double length;
  Tpoint refpt;
  double coefaux = 0.0;

  length = l * (2.0/3.0);
  DspMemberTrans_1 ( pi, dx, dy, length, coefi, coefaux );

  length = l / 3.0;
  refpt.x = ( pi->x ) + ( dx * (2.0/3.0) );
  refpt.y = ( pi->y ) + ( dy * (2.0/3.0) );
  DspMemberTrans_2 ( &refpt, dx, dy, length, coefaux, coefj );
}


/*                                                                  **
**  If the transversal component of the load in initial point is    **
**  negative and the absolute value is bigger then the final point  **
**                                                                  */
static void DspMemberTrans_6 (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the loaded member */
 double     l,  /* Length of the loaded member        */
 double coefi,  /* Coefficients that determinates the relations with the  */
 double coefj)  /* transversal load sizes at the initial and final points */

{
  /* Auxiliar variables */

  double length;
  Tpoint refpt;
  double coefaux = 0.0;

  length = l * (2.0/3.0);
  DspMemberTrans_2 ( pi, dx, dy, length, coefi, coefaux );

  length = l / 3.0;
  refpt.x = ( pi->x ) + ( dx * (2.0/3.0) );
  refpt.y = ( pi->y ) + ( dy * (2.0/3.0) );
  DspMemberTrans_1 ( &refpt, dx, dy, length, coefaux, coefj );
}


/*                                                                  **
**  If the transversal component of the load in initial point is    **
**  positive and the absolute value is the same of the final point  **
**                                                                  */
static void DspMemberTrans_7 (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the loaded member */
 double     l,  /* Length of the loaded member        */
 double coefi,  /* Coefficients that determinates the relations with the  */
 double coefj)  /* transversal load sizes at the initial and final points */

{
  /* Auxiliar variables */

  double length;
  Tpoint refpt;
  double coefaux = 0.0;

  length = l / 3.0;
  DspMemberTrans_1 ( pi, dx, dy, length, coefi, coefaux );

  length = l * (2.0/3.0);
  refpt.x = ( pi->x ) + ( dx / 3.0 );
  refpt.y = ( pi->y ) + ( dy / 3.0 );
  DspMemberTrans_2 ( &refpt, dx, dy, length, coefaux, coefj );
}


/*                                                                  **
**  If the transversal component of the load in initial point is    **
**  negative and the absolute value is the same of the final point  **
**                                                                  */
static void DspMemberTrans_8 (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the loaded member */
 double     l,  /* Length of the loaded member        */
 double coefi,  /* Coefficients that determinates the relations with the  */
 double coefj)  /* transversal load sizes at the initial and final points */

{
  /* Auxiliar variables */

  double length;
  Tpoint refpt;
  double coefaux = 0.0;

  length = l / 3.0;
  DspMemberTrans_2 ( pi, dx, dy, length, coefi, coefaux );

  length = l * (2.0/3.0);
  refpt.x = ( pi->x ) + ( dx / 3.0 );
  refpt.y = ( pi->y ) + ( dy / 3.0 );
  DspMemberTrans_1 ( &refpt, dx, dy, length, coefaux, coefj );
}


/*                                       **
**  This function displays the positive  **
**  transversal component value of the   **
**  member load                          **
**                                       */
static void DspMemberTransVal_1 (

 Tpoint *pi,    /* Point that defines the begin of the load */
 double dx,     /* Horizontal and vertical components */
 double dy,     /* of the length of the loaded member */
 double len,    /* Length of the loaded member        */
 double coeff,  /* Coefficient that defines the size of the transversal load */
 int    pos,    /* code for member position (ini, ctr, end) */
 double qy )    /* transversal load value */

{
 Tpoint charup;
 Tpoint p;
 double locx;
 double locy;
 double shift;
 int    align;

 sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.dist_load),
                  FtoolConvFromRefUnit(Ftool.unt.dist_load, qy) );
 FtoolShrinkExp( dvalue );
 sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.dist_load] );

 locx = 0.1 * size_trld;
 locy = (coeff * size_trld) + size_lold;
 shift = 0.25 * size_txt;

 switch( pos )
 {
  case MEMBER_INI:
   GraBackOpacity( GRA_OPAQUE );
   p.x = locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_WEST;
    p.y = - locy - shift;
   }
   else
   {
    align = GRA_SOUTH_EAST;
    p.y = - locy - shift;
   }
   break;
  default:
  case MEMBER_CTR:
   GraBackOpacity( GRA_TRANSPARENT );
   p.x = (len*0.5) + locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_WEST;
    p.y = - locy - shift;
   }
   else
   {
    align = GRA_SOUTH_EAST;
    p.y = - locy - shift;
   }
   break;
  case MEMBER_END:
   GraBackOpacity( GRA_OPAQUE );
   p.x = len - locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_EAST;
    p.y = - locy - shift;
   }
   else
   {
    align = GRA_SOUTH_WEST;
    p.y = - locy - shift;
   }
   break;
 }
 DspUtlChangeSystemLG( dx, dy, pi, &p, 1 );

 if( DspUtlDefOrientation( dx, dy ) )
 {
  charup.x = -dy;
  charup.y = dx;
 }
 else
 {
  charup.x = dy;
  charup.y = -dx;
 }
 GraSetTextCharUp( charup.x, charup.y );

 GraSetTextAlign( align );
 GraText( &p, dtext );
 GraBackOpacity( GRA_TRANSPARENT );
}


/*                                       **
**  This function displays the negative  **
**  transversal component value of the   **
**  member load                          **
**                                       */
static void DspMemberTransVal_2 (

 Tpoint *pi,    /* Point that defines the begin of the load */
 double dx,     /* Horizontal and vertical components */
 double dy,     /* of the length of the loaded member */
 double len,    /* Length of the loaded member        */
 double coeff,  /* Coefficient that defines the size of the transversal load */
 int    pos,    /* code for member position (ini, ctr, end) */
 double qy )    /* transversal load value */

{
 Tpoint charup;
 Tpoint p;
 double locx;
 double locy;
 double shift;
 int    align;

 sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.dist_load),
                  FtoolConvFromRefUnit(Ftool.unt.dist_load, fabs(qy)) );
 FtoolShrinkExp( dvalue );
 sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.dist_load] );

 locx = 0.1 * size_trld;
 locy = (coeff * size_trld) + size_lold;
 shift = 0.25 * size_txt;

 switch( pos )
 {
  case MEMBER_INI:
   GraBackOpacity( GRA_OPAQUE );
   p.x = locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_WEST;
    p.y = locy + shift;
   }
   else
   {
    align = GRA_NORTH_EAST;
    p.y = locy + shift;
   }
   break;
  default:
  case MEMBER_CTR:
   GraBackOpacity( GRA_TRANSPARENT );
   p.x = (len*0.5) + locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_WEST;
    p.y = locy + shift;
   }
   else
   {
    align = GRA_NORTH_EAST;
    p.y = locy + shift;
   }
   break;
  case MEMBER_END:
   GraBackOpacity( GRA_OPAQUE );
   p.x = len - locx;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_EAST;
    p.y = locy + shift;
   }
   else
   {
    align = GRA_NORTH_WEST;
    p.y = locy + shift;
   }
   break;
 }
 DspUtlChangeSystemLG( dx, dy, pi, &p, 1 );

 if( DspUtlDefOrientation( dx, dy ) )
 {
  charup.x = -dy;
  charup.y = dx;
 }
 else
 {
  charup.x = dy;
  charup.y = -dx;
 }
 GraSetTextCharUp( charup.x, charup.y );

 GraSetTextAlign( align );
 GraText( &p, dtext );
 GraBackOpacity( GRA_TRANSPARENT );
}


/*                                                 **
**  This function displays the global distributed  **
**  load with positive transversal component       **
**                                                 */
static void DspMemberGlobal_1 (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the loaded member */
 double     l,  /* Length of the loaded member        */
 double    lx,  /* Horizontal and vertical components */
 double    ly,  /* of the load unit direction         */
 double coefi,  /* Coefficients that determinates the relations with the  */
 double coefj)  /* transversal load sizes at the initial and final points */

{
  /* Auxiliar variables */

  int i;
  double dl;
  int    nseg;
  Tpoint head, underline[2], line1[2], line2[3], line3[2], line4[3];
  double dot_prod, space_fac, begin, size_fac, limit_fac;

  /* This function will display many forces in load direction. */
  /* Between each force it's necessary to define a space.      */

  /* This is an adjustment with this space and the length of the member.  */
  /* This space is increased depending on the direction of the force with */
  /* respect to the member direction (based on the dot product between    */
  /* the force unit direction and the member unit direction).             */

  dot_prod = fabs(dx * lx + dy * ly) / sqrt(dx*dx + dy*dy);
  space_fac = 1.0 + (2.0 * dot_prod * dot_prod);
  dl = size_trld * 0.5 * space_fac;  /* space to draw the force */
  nseg = (int)(l / dl);
  dl = l / (double)nseg;

  /* build and draw the "underline" of the load (positive in LS) */

  underline[0].x = 0.0;
  underline[0].y = - offset_gbld;
  underline[1].x = l;
  underline[1].y = - offset_gbld;

  DspUtlChangeSystemLG ( dx, dy, pi, underline, 2 );

  underline[0].x -= ( coefi * size_trld ) * lx;
  underline[0].y -= ( coefi * size_trld ) * ly;
  underline[1].x -= ( coefj * size_trld ) * lx;
  underline[1].y -= ( coefj * size_trld ) * ly;

  GraPolyLine ( 2, underline );

  /* Create a force arrow at the origin with default size 
     in the load direction */

  head.x = 0.0;
  head.y = 0.0;
  line1[0].x = - size_trld;
  line1[0].y = 0.0;
  line1[1].x = head.x;
  line1[1].y = head.y;

  line2[0].x = line1[1].x - ( size_trld * 0.15 );
  line2[0].y = line1[1].y - ( size_trld * 0.15 );
  line2[1].x = line1[1].x;
  line2[1].y = line1[1].y;
  line2[2].x = line1[1].x - ( size_trld * 0.15 );
  line2[2].y = line1[1].y + ( size_trld * 0.15 );

  DspUtlChangeSystemLG ( lx, ly, &head, line1, 2 );
  DspUtlChangeSystemLG ( lx, ly, &head, line2, 3 );

  /* Size_fac and limit_fac are size factors to draw the forces */

  if (!coefi)
  {
    begin = l;
    size_fac = coefj;
  }
  else
  {
    begin = 0.0;
    size_fac = coefi;
  }
  limit_fac = 0.2;

  for ( i=0; (i<=nseg) && (size_fac > limit_fac); i++ )
  {
    /* find head location */

    head.x = begin;
    head.y = - offset_gbld;
    DspUtlChangeSystemLG ( dx, dy, pi, &head, 1 );

    /* build each force */

    line3[0].x = head.x + line1[0].x * size_fac;
    line3[0].y = head.y + line1[0].y * size_fac;
    line3[1].x = head.x + line1[1].x;
    line3[1].y = head.y + line1[1].y;

    line4[0].x = head.x + line2[0].x;
    line4[0].y = head.y + line2[0].y;
    line4[1].x = head.x + line2[1].x;
    line4[1].y = head.y + line2[1].y;
    line4[2].x = head.x + line2[2].x;
    line4[2].y = head.y + line2[2].y;

    /* draw each force */

    GraPolyLine ( 2, line3 );
    GraPolyLine ( 3, line4 );

    /* adjust the position and size factor to draw the force */

    if (!coefi)
    {
      begin -= dl;
      size_fac -= coefj * ( dl / l );
    }
    else
    {
      begin += dl;
      size_fac += ( coefj - coefi ) * ( dl / l );
    }
  }
}


/*                                                 **
**  This function displays the global distributed  **
**  load with negative transversal component       **
**                                                 */
static void DspMemberGlobal_2 (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the loaded member */
 double     l,  /* Length of the loaded member        */
 double    lx,  /* Horizontal and vertical components */
 double    ly,  /* of the load unit direction         */
 double coefi,  /* Coefficients that determinates the relations with the  */
 double coefj)  /* transversal load sizes at the initial and final points */

{
  /* Auxiliar variables */

  int i;
  double dl;
  int    nseg;
  Tpoint head, topline[2], line1[2], line2[3], line3[2], line4[3];
  double dot_prod, space_fac, begin, size_fac, limit_fac;

  /* This function will display many forces in load direction. */
  /* Between each force it's necessary to define a space.      */

  /* This is an adjustment with this space and the length of the member.  */
  /* This space is increased depending on the direction of the force with */
  /* respect to the member direction (based on the dot product between    */
  /* the force unit direction and the member unit direction).             */

  dot_prod = fabs(dx * lx + dy * ly) / sqrt(dx*dx + dy*dy);
  space_fac = 1.0 + (2.0 * dot_prod * dot_prod);
  dl = size_trld * 0.5 * space_fac;  /* space to draw the force */
  nseg = (int)(l / dl);
  dl = l / (double)nseg;

  /* build and draw the "topline" of the load (negative in LS) */

  topline[0].x = 0.0;
  topline[0].y = offset_gbld;
  topline[1].x = l;
  topline[1].y = offset_gbld;

  DspUtlChangeSystemLG ( dx, dy, pi, topline, 2 );

  topline[0].x -= ( coefi * size_trld ) * lx;
  topline[0].y -= ( coefi * size_trld ) * ly;
  topline[1].x -= ( coefj * size_trld ) * lx;
  topline[1].y -= ( coefj * size_trld ) * ly;

  GraPolyLine ( 2, topline );

  /* Create a force arrow at the origin with default size 
     in the load direction */

  head.x = 0.0;
  head.y = 0.0;
  line1[0].x = - size_trld;
  line1[0].y = 0.0;
  line1[1].x = head.x;
  line1[1].y = head.y;

  line2[0].x = line1[1].x - ( size_trld * 0.15 );
  line2[0].y = line1[1].y - ( size_trld * 0.15 );
  line2[1].x = line1[1].x;
  line2[1].y = line1[1].y;
  line2[2].x = line1[1].x - ( size_trld * 0.15 );
  line2[2].y = line1[1].y + ( size_trld * 0.15 );

  DspUtlChangeSystemLG ( lx, ly, &head, line1, 2 );
  DspUtlChangeSystemLG ( lx, ly, &head, line2, 3 );

  /* Size_fac and limit_fac are size factors to draw the forces */

  if (!coefi)
  {
    begin = l;
    size_fac = coefj;
  }
  else
  {
    begin = 0.0;
    size_fac = coefi;
  }
  limit_fac = 0.2;

  for ( i=0; (i<=nseg) && (size_fac > limit_fac); i++ )
  {
    /* find head location */

    head.x = begin;
    head.y = offset_gbld;
    DspUtlChangeSystemLG ( dx, dy, pi, &head, 1 );

    /* build each force */

    line3[0].x = head.x + line1[0].x * size_fac;
    line3[0].y = head.y + line1[0].y * size_fac;
    line3[1].x = head.x + line1[1].x;
    line3[1].y = head.y + line1[1].y;

    line4[0].x = head.x + line2[0].x;
    line4[0].y = head.y + line2[0].y;
    line4[1].x = head.x + line2[1].x;
    line4[1].y = head.y + line2[1].y;
    line4[2].x = head.x + line2[2].x;
    line4[2].y = head.y + line2[2].y;

    /* draw each force */

    GraPolyLine ( 2, line3 );
    GraPolyLine ( 3, line4 );

    /* adjust the position and size factor to draw the force */

    if (!coefi)
    {
      begin -= dl;
      size_fac -= coefj * ( dl / l );
    }
    else
    {
      begin += dl;
      size_fac += ( coefj - coefi ) * ( dl / l );
    }
  }
}


/*                                                 **
**  This function displays the value of the global **
**  distributed load with positive transversal     **
**  component                                      **
**                                                 */
static void DspMemberGlobalVal_1 (
 
 Tpoint *pi,    /* Point that defines the begin of the load */
 double dx,     /* Horizontal and vertical components */
 double dy,     /* of the length of the loaded member */
 double len,    /* Length of the loaded member        */
 double lx,     /* Horizontal and vertical components */
 double ly,     /* of the load unit direction         */
 double coeff,  /* Coefficient that defines the size of the transversal load */
 int    pos,    /* code for member position (ini, ctr, end) */
 double q )     /* distributed load value */

{
 Tpoint charup;
 Tpoint p;
 double shift;
 int    align;

 sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.dist_load),
                  FtoolConvFromRefUnit(Ftool.unt.dist_load, q) );
 FtoolShrinkExp( dvalue );
 sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.dist_load] );

 shift = 0.25 * size_txt;

 switch( pos )
 {
  case MEMBER_INI:
   GraBackOpacity( GRA_OPAQUE );
   p.x = 0.1 * size_trld;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_WEST;
    p.y = - offset_gbld - shift;
   }
   else
   {
    align = GRA_SOUTH_EAST;
    p.y = - offset_gbld - shift;
   }
   break;
  default:
  case MEMBER_CTR:
   GraBackOpacity( GRA_TRANSPARENT );
   p.x = (len*0.5) + (0.1*size_trld);
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_WEST;
    p.y = - offset_gbld - shift;
   }
   else
   {
    align = GRA_SOUTH_EAST;
    p.y = - offset_gbld - shift;
   }
   break;
  case MEMBER_END:
   GraBackOpacity( GRA_OPAQUE );
   p.x = len - (0.1*size_trld);
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_EAST;
    p.y = - offset_gbld - shift;
   }
   else
   {
    align = GRA_SOUTH_WEST;
    p.y = - offset_gbld - shift;
   }
   break;
 }
 DspUtlChangeSystemLG( dx, dy, pi, &p, 1 );

 p.x -= ( coeff * size_trld ) * lx;
 p.y -= ( coeff * size_trld ) * ly;

 if( DspUtlDefOrientation( dx, dy ) )
 {
  charup.x = -dy;
  charup.y = dx;
 }
 else
 {
  charup.x = dy;
  charup.y = -dx;
 }
 GraSetTextCharUp( charup.x, charup.y );

 GraSetTextAlign( align );
 GraText( &p, dtext );
 GraBackOpacity( GRA_TRANSPARENT );
}


/*                                                 **
**  This function displays the value of the global **
**  distributed load with negative transversal     **
**  component                                      **
**                                                 */
static void DspMemberGlobalVal_2 (
 
 Tpoint *pi,    /* Point that defines the begin of the load */
 double dx,     /* Horizontal and vertical components */
 double dy,     /* of the length of the loaded member */
 double len,    /* Length of the loaded member        */
 double lx,     /* Horizontal and vertical components */
 double ly,     /* of the load unit direction         */
 double coeff,  /* Coefficient that defines the size of the transversal load */
 int    pos,    /* code for member position (ini, ctr, end) */
 double q )     /* distributed load value */

{
 Tpoint charup;
 Tpoint p;
 double shift;
 int    align;

 sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.dist_load),
                  FtoolConvFromRefUnit(Ftool.unt.dist_load, fabs(q)) );
 FtoolShrinkExp( dvalue );
 sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.dist_load] );

 shift = 0.25 * size_txt;

 switch( pos )
 {
  case MEMBER_INI:
   GraBackOpacity( GRA_OPAQUE );
   p.x = 0.1 * size_trld;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_WEST;
    p.y = offset_gbld + shift;
   }
   else
   {
    align = GRA_NORTH_EAST;
    p.y = offset_gbld + shift;
   }
   break;
  default:
  case MEMBER_CTR:
   GraBackOpacity( GRA_TRANSPARENT );
   p.x = (len*0.5) + (0.1*size_trld);
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_WEST;
    p.y = offset_gbld + shift;
   }
   else
   {
    align = GRA_NORTH_EAST;
    p.y = offset_gbld + shift;
   }
   break;
  case MEMBER_END:
   GraBackOpacity( GRA_OPAQUE );
   p.x = len - (0.1*size_trld);
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_EAST;
    p.y = offset_gbld + shift;
   }
   else
   {
    align = GRA_NORTH_WEST;
    p.y = offset_gbld + shift;
   }
   break;
 }
 DspUtlChangeSystemLG( dx, dy, pi, &p, 1 );

 p.x -= ( coeff * size_trld ) * lx;
 p.y -= ( coeff * size_trld ) * ly;

 if( DspUtlDefOrientation( dx, dy ) )
 {
  charup.x = -dy;
  charup.y = dx;
 }
 else
 {
  charup.x = dy;
  charup.y = -dx;
 }
 GraSetTextCharUp( charup.x, charup.y );

 GraSetTextAlign( align );
 GraText( &p, dtext );
 GraBackOpacity( GRA_TRANSPARENT );
}


/*                                            **
**  This function displays the thermal loads  **
**                                            */

void DspThermalLoad (

 Tpoint   *pi,     /* Points that define the begin                   */
 Tpoint   *pj,     /* and the end of the load                        */
 double   top,     /* The thermal load at the top member fiber       */
 double   bot,     /* The thermal load at the bottom member fiber    */
 int      colour)  /* Colour's flames draw                           */

{
  double  dx;       /* Horizontal and vertical components */
  double  dy;       /* of the length of the loaded member */
  double  l;        /* Length of the loaded member        */
  int     backfill; /* flag to fill flame color with back color */

  if ( (fabs (top) < TOLELL) && (fabs (bot) < TOLELL) )
    return;

  size_txt = dsp_sizetxt;
  GraSetTextHeight( size_txt );

  /* set the foreground flame color */
  GraSetLineColor (colour);
  GraSetTextColor (colour);

  /* set the fill flame color flag */
  if( colour == Color.back )
   backfill = 1;
  else
   backfill = 0;

  /* set the thermal load size */
  size_trld = 0.4 * dsp_sizel;

  /* calculation of the length of the loaded member */

  dy = (pj->y) - (pi->y);
  dx = (pj->x) - (pi->x);
  l = sqrt ( dx*dx + dy*dy );

  if ( fabs (top) < TOLELL )
    top = 0.0;

  if ( fabs (bot) < TOLELL )
    bot = 0.0;

  if (top > 0.0)
  {
    DspMemberTopHeat ( pi, top, dx, dy, l, backfill );
  }
  else if (top < 0.0 )
  {
    DspMemberTopCool ( pi, top, dx, dy, l );
  }

  if (bot > 0.0)
  {
    DspMemberBotHeat ( pi, bot, dx, dy, l, backfill );
  }
  else if (bot < 0.0 )
  {
    DspMemberBotCool ( pi, bot, dx, dy, l );
  }
}


/*                                       **
**  This function displays the heating   **
**  load at the top fibers               **
**                                       */
static void DspMemberTopHeat (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double   top,  /* The heating load at the top member fiber */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the heated member */
 double     l,  /* Length of the heated member        */
 int      backfill) /* flag to fill flame color with back color */

{
  /* Auxiliar variables */

  int i, j;
  double dl;
  int    nseg;
  Tpoint underline[2];
  double underspace;    /* space between member and under line */
  Tpoint flame1[NFlame1Pts];
  Tpoint flame2[NFlame2Pts];
  double begin;

  /* This function will display many flames in transversal direction.
   * Between each flame it's necessary to define a space, which is 
   * initially the size of the transversal load (size of flame).
   * It is made an adjustment with this space based on the length 
   * of the member  */

  dl = size_trld;       /* space to draw the flames */
  nseg = (int)(l / dl);
  dl = l / (double)nseg;

  underspace = size_trld / 3.0;

  begin = dl;
  for ( i=0; i<nseg-1; i++ )
  {
    /* build each flame */

    for ( j=0; j<NFlame1Pts; j++ )
    {
     flame1[j].x = (flameprtv1[j].x * size_trld) + begin;
     flame1[j].y = (flameprtv1[j].y * size_trld) + underspace;
    }
 
    for ( j=0; j<NFlame2Pts; j++ )
    {
     flame2[j].x = (flameprtv2[j].x * size_trld) + begin;
     flame2[j].y = (flameprtv2[j].y * size_trld) + underspace;
    }

    /* change to global system */

    DspUtlChangeSystemLG ( dx, dy, pi, flame1, NFlame1Pts );
    DspUtlChangeSystemLG ( dx, dy, pi, flame2, NFlame2Pts );

    /* draw each flame */

    if( backfill )
     GraSetFillColor ( Color.back );
    else
     GraSetFillColor ( Color.flame );
    GraFillArea ( NFlame1Pts, flame1 );
    if( backfill )
     GraSetFillColor ( Color.back );
    else
     GraSetFillColor ( Color.flamecore );
    GraFillArea ( NFlame2Pts, flame2 );

    GraPolyLine ( NFlame1Pts, flame1 );
    GraPolyLine ( NFlame2Pts, flame2 );

    /* adjust the position to draw the flame */

    begin += dl;
  }

  /* build and draw the "underline" of the flame (top fiber) */

  underline[0].x = dl * 0.5;
  underline[0].y = underspace;
  underline[1].x = l - (dl * 0.5);
  underline[1].y = underspace;

  DspUtlChangeSystemLG ( dx, dy, pi, underline, 2 );

  GraPolyLine ( 2, underline );

 /* display temperature value */

  if( VisLoadVal == ON )
  {
   Tpoint charup;
   Tpoint p;
   double shift;
   int    align;

   sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.temperature),
                    FtoolConvFromRefUnit(Ftool.unt.temperature, top) );
   FtoolShrinkExp( dvalue );
   sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.temperature] );

   shift = 0.15 * size_txt;

   p.x = (l*0.5) - size_trld;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_EAST;
    p.y = underspace + size_trld + shift;
   }
   else
   {
    align = GRA_NORTH_WEST;
    p.y = underspace + size_trld + shift;
   }
   DspUtlChangeSystemLG( dx, dy, pi, &p, 1 );

   if( DspUtlDefOrientation( dx, dy ) )
   {
    charup.x = -dy;
    charup.y = dx;
   }
   else
   {
    charup.x = dy;
    charup.y = -dx;
   }
   GraSetTextCharUp( charup.x, charup.y );

   GraSetTextAlign( align );
   GraBackOpacity( GRA_OPAQUE );
   GraText( &p, dtext );
   GraBackOpacity( GRA_TRANSPARENT );
  }
}


/*                                       **
**  This function displays the heating   **
**  load at the bottom fibers            **
**                                       */
static void DspMemberBotHeat (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double   bot,  /* The heating load at the bottom member fiber */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the heated member */
 double     l,  /* Length of the heated member        */
 int      backfill) /* flag to fill flame color with back color */

{
  /* Auxiliar variables */

  int i, j;
  double dl;
  int    nseg;
  Tpoint underline[2];
  double underspace;    /* space between member and under line */
  Tpoint flame1[NFlame1Pts];
  Tpoint flame2[NFlame2Pts];
  double begin;

  /* This function will display many flames in transversal direction.
   * Between each flame it's necessary to define a space, which is 
   * initially the size of the transversal load (size of flame).
   * It is made an adjustment with this space based on the length 
   * of the member  */

  dl = size_trld;       /* space to draw the flames */
  nseg = (int)(l / dl);
  dl = l / (double)nseg;

  underspace = size_trld / 3.0;

  begin = dl;
  for ( i=0; i<nseg-1; i++ )
  {
    /* build each flame */

    for ( j=0; j<NFlame1Pts; j++ )
    {
     flame1[j].x = (flameprtv1[j].x * size_trld) + begin;
     flame1[j].y = ((1.0-flameprtv1[j].y) * size_trld) - size_trld - underspace;
    }
 
    for ( j=0; j<NFlame2Pts; j++ )
    {
     flame2[j].x = (flameprtv2[j].x * size_trld) + begin;
     flame2[j].y = ((1.0-flameprtv2[j].y) * size_trld) - size_trld - underspace;
    }

    /* change to global system */

    DspUtlChangeSystemLG ( dx, dy, pi, flame1, NFlame1Pts );
    DspUtlChangeSystemLG ( dx, dy, pi, flame2, NFlame2Pts );

    /* draw each flame */

    if( backfill )
     GraSetFillColor ( Color.back );
    else
     GraSetFillColor ( Color.flame );
    GraFillArea ( NFlame1Pts, flame1 );
    if( backfill )
     GraSetFillColor ( Color.back );
    else
     GraSetFillColor ( Color.flamecore );
    GraFillArea ( NFlame2Pts, flame2 );

    GraPolyLine ( NFlame1Pts, flame1 );
    GraPolyLine ( NFlame2Pts, flame2 );

    /* adjust the position to draw the flame */

    begin += dl;
  }

  /* build and draw the "underline" of the flame (top fiber) */

  underline[0].x = dl * 0.5;
  underline[0].y = - underspace;
  underline[1].x = l - (dl * 0.5);
  underline[1].y = - underspace;

  DspUtlChangeSystemLG ( dx, dy, pi, underline, 2 );

  GraPolyLine ( 2, underline );

 /* display temperature value */

  if( VisLoadVal == ON )
  {
   Tpoint charup;
   Tpoint p;
   double shift;
   int    align;

   sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.temperature),
                    FtoolConvFromRefUnit(Ftool.unt.temperature, bot) );
   FtoolShrinkExp( dvalue );
   sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.temperature] );

   shift = 0.15 * size_txt;

   p.x = (l*0.5) - size_trld;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_EAST;
    p.y = - underspace - size_trld - shift;
   }
   else
   {
    align = GRA_SOUTH_WEST;
    p.y = - underspace - size_trld - shift;
   }
   DspUtlChangeSystemLG( dx, dy, pi, &p, 1 );

   if( DspUtlDefOrientation( dx, dy ) )
   {
    charup.x = -dy;
    charup.y = dx;
   }
   else
   {
    charup.x = dy;
    charup.y = -dx;
   }
   GraSetTextCharUp( charup.x, charup.y );

   GraSetTextAlign( align );
   GraBackOpacity( GRA_OPAQUE );
   GraText( &p, dtext );
   GraBackOpacity( GRA_TRANSPARENT );
  }
}


/*                                       **
**  This function displays the cooling   **
**  load at the top fibers               **
**                                       */
static void DspMemberTopCool (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double   top,  /* The cooling load at the top member fiber */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the cooled member */
 double     l)  /* Length of the cooled member        */

{
  /* Auxiliar variables */

  int i, j;
  double dl;
  int    nseg;
  Tpoint underline[2];
  double underspace;    /* space between member and under line */
  double begin;
  Tpoint flake01[2];
  Tpoint flake02[2];
  Tpoint flake03[2];
  Tpoint flake04[2];
  Tpoint flake05[2];
  Tpoint flake06[2];
  Tpoint flake07[2];
  Tpoint flake08[2];
  Tpoint flake09[2];
  Tpoint flake10[2];
  Tpoint flake11[2];
  Tpoint flake12[2];

  /* This function will display many flakes in transversal direction.
   * Between each flake it's necessary to define a space, which is 
   * initially the size of the transversal load (size of flake).
   * It is made an adjustment with this space based on the length 
   * of the member  */

  dl = 1.2 * size_trld;       /* space to draw the flakes */
  nseg = (int)(l / dl);
  dl = l / (double)nseg;

  underspace = size_trld / 3.0;

  begin = dl;
  for ( i=0; i<nseg-1; i++ )
  {
    /* build each flake */

    for ( j=0; j<2; j++ )
    {
     flake01[j].x = (flakeprtv01[j].x * size_trld) + begin;
     flake01[j].y = (flakeprtv01[j].y * size_trld) + underspace;
     flake02[j].x = (flakeprtv02[j].x * size_trld) + begin;
     flake02[j].y = (flakeprtv02[j].y * size_trld) + underspace;
     flake03[j].x = (flakeprtv03[j].x * size_trld) + begin;
     flake03[j].y = (flakeprtv03[j].y * size_trld) + underspace;
     flake04[j].x = (flakeprtv04[j].x * size_trld) + begin;
     flake04[j].y = (flakeprtv04[j].y * size_trld) + underspace;
     flake05[j].x = (flakeprtv05[j].x * size_trld) + begin;
     flake05[j].y = (flakeprtv05[j].y * size_trld) + underspace;
     flake06[j].x = (flakeprtv06[j].x * size_trld) + begin;
     flake06[j].y = (flakeprtv06[j].y * size_trld) + underspace;
     flake07[j].x = (flakeprtv07[j].x * size_trld) + begin;
     flake07[j].y = (flakeprtv07[j].y * size_trld) + underspace;
     flake08[j].x = (flakeprtv08[j].x * size_trld) + begin;
     flake08[j].y = (flakeprtv08[j].y * size_trld) + underspace;
     flake09[j].x = (flakeprtv09[j].x * size_trld) + begin;
     flake09[j].y = (flakeprtv09[j].y * size_trld) + underspace;
     flake10[j].x = (flakeprtv10[j].x * size_trld) + begin;
     flake10[j].y = (flakeprtv10[j].y * size_trld) + underspace;
     flake11[j].x = (flakeprtv11[j].x * size_trld) + begin;
     flake11[j].y = (flakeprtv11[j].y * size_trld) + underspace;
     flake12[j].x = (flakeprtv12[j].x * size_trld) + begin;
     flake12[j].y = (flakeprtv12[j].y * size_trld) + underspace;
    }

    /* change to global system */

    DspUtlChangeSystemLG ( dx, dy, pi, flake01, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake02, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake03, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake04, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake05, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake06, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake07, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake08, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake09, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake10, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake11, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake12, 2 );

    /* draw each flake */

    GraPolyLine ( 2, flake01 );
    GraPolyLine ( 2, flake02 );
    GraPolyLine ( 2, flake03 );
    GraPolyLine ( 2, flake04 );
    GraPolyLine ( 2, flake05 );
    GraPolyLine ( 2, flake06 );
    GraPolyLine ( 2, flake07 );
    GraPolyLine ( 2, flake08 );
    GraPolyLine ( 2, flake09 );
    GraPolyLine ( 2, flake10 );
    GraPolyLine ( 2, flake11 );
    GraPolyLine ( 2, flake12 );

    /* adjust the position to draw the flake */

    begin += dl;
  }

  /* build and draw the "underline" of the flake (top fiber) */

  underline[0].x = dl * 0.5;
  underline[0].y = underspace;
  underline[1].x = l - (dl * 0.5);
  underline[1].y = underspace;

  DspUtlChangeSystemLG ( dx, dy, pi, underline, 2 );

  GraPolyLine ( 2, underline );

 /* display temperature value */

  if( VisLoadVal == ON )
  {
   Tpoint charup;
   Tpoint p;
   double shift;
   int    align;

   sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.temperature),
                    FtoolConvFromRefUnit(Ftool.unt.temperature, top) );
   FtoolShrinkExp( dvalue );
   sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.temperature] );

   shift = 0.15 * size_txt;

   p.x = (l*0.5) - size_trld;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_SOUTH_EAST;
    p.y = underspace + size_trld + shift;
   }
   else
   {
    align = GRA_NORTH_WEST;
    p.y = underspace + size_trld + shift;
   }
   DspUtlChangeSystemLG( dx, dy, pi, &p, 1 );

   if( DspUtlDefOrientation( dx, dy ) )
   {
    charup.x = -dy;
    charup.y = dx;
   }
   else
   {
    charup.x = dy;
    charup.y = -dx;
   }
   GraSetTextCharUp( charup.x, charup.y );

   GraSetTextAlign( align );
   GraBackOpacity( GRA_OPAQUE );
   GraText( &p, dtext );
   GraBackOpacity( GRA_TRANSPARENT );
  }
}


/*                                       **
**  This function displays the cooling   **
**  load at the bottom fibers            **
**                                       */
static void DspMemberBotCool (

 Tpoint   *pi,  /* Point that defines the begin of the load */
 double   bot,  /* The cooling load at the bottom member fiber */
 double    dx,  /* Horizontal and vertical components */
 double    dy,  /* of the length of the cooled member */
 double     l)  /* Length of the cooled member        */

{
  /* Auxiliar variables */

  int i, j;
  double dl;
  int    nseg;
  Tpoint underline[2];
  double underspace;    /* space between member and under line */
  double begin;
  Tpoint flake01[2];
  Tpoint flake02[2];
  Tpoint flake03[2];
  Tpoint flake04[2];
  Tpoint flake05[2];
  Tpoint flake06[2];
  Tpoint flake07[2];
  Tpoint flake08[2];
  Tpoint flake09[2];
  Tpoint flake10[2];
  Tpoint flake11[2];
  Tpoint flake12[2];

  /* This function will display many flakes in transversal direction.
   * Between each flake it's necessary to define a space, which is 
   * initially the size of the transversal load (size of flake).
   * It is made an adjustment with this space based on the length 
   * of the member  */

  dl = 1.2 * size_trld;       /* space to draw the flakes */
  nseg = (int)(l / dl);
  dl = l / (double)nseg;

  underspace = size_trld / 3.0;

  begin = dl;
  for ( i=0; i<nseg-1; i++ )
  {
    /* build each flake */

    for ( j=0; j<2; j++ )
    {
     flake01[j].x = (flakeprtv01[j].x * size_trld) + begin;
     flake01[j].y = ((1.0-flakeprtv01[j].y)*size_trld) - size_trld - underspace;
     flake02[j].x = (flakeprtv02[j].x * size_trld) + begin;
     flake02[j].y = ((1.0-flakeprtv02[j].y)*size_trld) - size_trld - underspace;
     flake03[j].x = (flakeprtv03[j].x * size_trld) + begin;
     flake03[j].y = ((1.0-flakeprtv03[j].y)*size_trld) - size_trld - underspace;
     flake04[j].x = (flakeprtv04[j].x * size_trld) + begin;
     flake04[j].y = ((1.0-flakeprtv04[j].y)*size_trld) - size_trld - underspace;
     flake05[j].x = (flakeprtv05[j].x * size_trld) + begin;
     flake05[j].y = ((1.0-flakeprtv05[j].y)*size_trld) - size_trld - underspace;
     flake06[j].x = (flakeprtv06[j].x * size_trld) + begin;
     flake06[j].y = ((1.0-flakeprtv06[j].y)*size_trld) - size_trld - underspace;
     flake07[j].x = (flakeprtv07[j].x * size_trld) + begin;
     flake07[j].y = ((1.0-flakeprtv07[j].y)*size_trld) - size_trld - underspace;
     flake08[j].x = (flakeprtv08[j].x * size_trld) + begin;
     flake08[j].y = ((1.0-flakeprtv08[j].y)*size_trld) - size_trld - underspace;
     flake09[j].x = (flakeprtv09[j].x * size_trld) + begin;
     flake09[j].y = ((1.0-flakeprtv09[j].y)*size_trld) - size_trld - underspace;
     flake10[j].x = (flakeprtv10[j].x * size_trld) + begin;
     flake10[j].y = ((1.0-flakeprtv10[j].y)*size_trld) - size_trld - underspace;
     flake11[j].x = (flakeprtv11[j].x * size_trld) + begin;
     flake11[j].y = ((1.0-flakeprtv11[j].y)*size_trld) - size_trld - underspace;
     flake12[j].x = (flakeprtv12[j].x * size_trld) + begin;
     flake12[j].y = ((1.0-flakeprtv12[j].y)*size_trld) - size_trld - underspace;
    }

    /* change to global system */

    DspUtlChangeSystemLG ( dx, dy, pi, flake01, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake02, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake03, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake04, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake05, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake06, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake07, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake08, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake09, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake10, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake11, 2 );
    DspUtlChangeSystemLG ( dx, dy, pi, flake12, 2 );

    /* draw each flake */

    GraPolyLine ( 2, flake01 );
    GraPolyLine ( 2, flake02 );
    GraPolyLine ( 2, flake03 );
    GraPolyLine ( 2, flake04 );
    GraPolyLine ( 2, flake05 );
    GraPolyLine ( 2, flake06 );
    GraPolyLine ( 2, flake07 );
    GraPolyLine ( 2, flake08 );
    GraPolyLine ( 2, flake09 );
    GraPolyLine ( 2, flake10 );
    GraPolyLine ( 2, flake11 );
    GraPolyLine ( 2, flake12 );

    /* adjust the position to draw the flake */

    begin += dl;
  }

  /* build and draw the "underline" of the flake (bottom fiber) */

  underline[0].x = dl * 0.5;
  underline[0].y = - underspace;
  underline[1].x = l - (dl * 0.5);
  underline[1].y = - underspace;

  DspUtlChangeSystemLG ( dx, dy, pi, underline, 2 );

  GraPolyLine ( 2, underline );

 /* display temperature value */

  if( VisLoadVal == ON )
  {
   Tpoint charup;
   Tpoint p;
   double shift;
   int    align;

   sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.temperature),
                    FtoolConvFromRefUnit(Ftool.unt.temperature, bot) );
   FtoolShrinkExp( dvalue );
   sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.temperature] );

   shift = 0.15 * size_txt;

   p.x = (l*0.5) - size_trld;
   if( DspUtlDefOrientation( dx, dy ) )
   {
    align = GRA_NORTH_EAST;
    p.y = - underspace - size_trld - shift;
   }
   else
   {
    align = GRA_SOUTH_WEST;
    p.y = - underspace - size_trld - shift;
   }
   DspUtlChangeSystemLG( dx, dy, pi, &p, 1 );

   if( DspUtlDefOrientation( dx, dy ) )
   {
    charup.x = -dy;
    charup.y = dx;
   }
   else
   {
    charup.x = dy;
    charup.y = -dx;
   }
   GraSetTextCharUp( charup.x, charup.y );

   GraSetTextAlign( align );
   GraBackOpacity( GRA_OPAQUE );
   GraText( &p, dtext );
   GraBackOpacity( GRA_TRANSPARENT );
  }
}


/*                                                       **
**  This function displays the member end moments loads  **
**                                                       */

void DspMEndMomLoad (

 Tpoint   *pi,     /* Points that define the begin                   */
 Tpoint   *pj,     /* and the end of the member                      */
 double   ma,      /* Initial member moment                          */
 double   mb,      /* Final member moment                            */
 int      color)   /* Color to draw moments                          */

{
  double  dx;       /* Horizontal and vertical components */
  double  dy;       /* of the length of the loaded member */

  if ( (fabs (ma) < TOLELL) && (fabs (mb) < TOLELL) )
    return;

  size_txt = dsp_sizetxt;
  GraSetTextHeight( size_txt );

  /* set the foreground color */
  GraSetLineColor (color);
  GraSetFillColor (color);
  GraSetTextColor (color);

  /* set the moment sizes */
  size_n = dsp_sizenf;
  size_m = dsp_sizemom;

  /* calculation of the length of the loaded member */

  dy = pj->y - pi->y;
  dx = pj->x - pi->x;

  if( fabs (ma) < TOLELL )
    ma = 0.0;

  if( fabs (mb) < TOLELL )
    mb = 0.0;

  if( ma > 0.0 )
  {
   DspMemberMomA_1 ( pi, ma, dx, dy );
  }
  else if( ma < 0.0 )
  {
   DspMemberMomA_2 ( pi, ma, dx, dy );
  }

  if( mb > 0.0 )
  {
   DspMemberMomB_1 ( pj, mb, dx, dy );
  }
  else if( mb < 0.0 )
  {
   DspMemberMomB_2 ( pj, mb, dx, dy );
  }
}

/*                                                             **
**  This function displays the positive initial member moment  **
**                                                             */
static void DspMemberMomA_1 ( 

Tpoint *p,   /* Point location where the moment will be displayed */
double ma,   /* Moment value */
double dx,   /* Horizontal and vertical components */
double dy)   /* of the length of the loaded member */

{
 Tpoint tip, arrow[3], orig;
 double ang, ang1, ang2;

 orig.x = 0.0;
 orig.y = 0.0;
 arrow[0].x = + ( size_n * 0.10 );
 arrow[0].y = - ( size_n * 0.20 );
 arrow[1].x = 0.0;
 arrow[1].y = 0.0;
 arrow[2].x = - ( size_n * 0.10 );
 arrow[2].y = - ( size_n * 0.20 );
 DspUtlRotationPoints( PI/4.0, &orig, arrow, 3 );

 orig.x = -size_m*0.4;
 orig.y = 0.0;
 DspUtlChangeSystemLG( dx, dy, p, &orig, 1 );

 tip.x = size_m*0.5;
 tip.y = size_m*sin60;
 arrow[0].x += tip.x;
 arrow[0].y += tip.y;
 arrow[1].x += tip.x;
 arrow[1].y += tip.y;
 arrow[2].x += tip.x;
 arrow[2].y += tip.y;
 DspUtlChangeSystemLG( dx, dy, &orig, arrow, 3 );

 /* draw the moment */

 ang = DspUtlArcTg( dy, dx );
 ang1 = ToDeg( ang - PI/3.0 );
 ang2 = ToDeg( ang + PI/3.0 );

 GraArc ( &orig, size_m, ang1, ang2 );
 GraSetFillIntStyle ( GRA_SOLID );
 GraFillArea ( 3, arrow );

 /* display load value */

 if( VisLoadVal == ON )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;
  int    align;

  sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.moment),
                   FtoolConvFromRefUnit(Ftool.unt.moment, ma) );
  FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.moment] );

  shift = 0.05 * size_m;
  pos.x = tip.x + shift;
  pos.y = tip.y;
  DspUtlChangeSystemLG( dx, dy, &orig, &pos, 1 );

  if( DspUtlDefOrientation( dx, dy ) )
  {
   align = GRA_SOUTH_WEST;
  }
  else
  {
   align = GRA_NORTH_EAST;
  }

  if( DspUtlDefOrientation( dx, dy ) )
  {
   charup.x = -dy;
   charup.y = dx;
  }
  else
  {
   charup.x = dy;
   charup.y = -dx;
  }
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( align );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                             **
**  This function displays the negative initial member moment  **
**                                                             */
static void DspMemberMomA_2 ( 

Tpoint *p,   /* Point location where the moment will be displayed */
double ma,   /* Moment value */
double dx,   /* Horizontal and vertical components */
double dy)   /* of the length of the loaded member */

{
 Tpoint tip, arrow[3], orig;
 double ang, ang1, ang2;

 orig.x = 0.0;
 orig.y = 0.0;
 arrow[0].x = - ( size_n * 0.10 );
 arrow[0].y = + ( size_n * 0.20 );
 arrow[1].x = 0.0;
 arrow[1].y = 0.0;
 arrow[2].x = + ( size_n * 0.10 );
 arrow[2].y = + ( size_n * 0.20 );
 DspUtlRotationPoints( -PI/4.0, &orig, arrow, 3 );

 orig.x = -size_m*0.4;
 orig.y = 0.0;
 DspUtlChangeSystemLG( dx, dy, p, &orig, 1 );

 tip.x = size_m*0.5;
 tip.y = -size_m*sin60;
 arrow[0].x += tip.x;
 arrow[0].y += tip.y;
 arrow[1].x += tip.x;
 arrow[1].y += tip.y;
 arrow[2].x += tip.x;
 arrow[2].y += tip.y;
 DspUtlChangeSystemLG( dx, dy, &orig, arrow, 3 );

 /* draw the moment */

 ang = DspUtlArcTg( dy, dx );
 ang1 = ToDeg( ang - PI/3.0 );
 ang2 = ToDeg( ang + PI/3.0 );

 GraArc ( &orig, size_m, ang1, ang2 );
 GraSetFillIntStyle ( GRA_SOLID );
 GraFillArea ( 3, arrow );

 /* display load value */

 if( VisLoadVal == ON )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;
  int    align;

  sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.moment),
                   FtoolConvFromRefUnit(Ftool.unt.moment, fabs(ma)) );
  FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.moment] );

  shift = 0.05 * size_m;
  pos.x = tip.x + shift;
  pos.y = tip.y;
  DspUtlChangeSystemLG( dx, dy, &orig, &pos, 1 );

  if( DspUtlDefOrientation( dx, dy ) )
  {
   align = GRA_NORTH_WEST;
  }
  else
  {
   align = GRA_SOUTH_EAST;
  }

  if( DspUtlDefOrientation( dx, dy ) )
  {
   charup.x = -dy;
   charup.y = dx;
  }
  else
  {
   charup.x = dy;
   charup.y = -dx;
  }
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( align );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                           **
**  This function displays the positive final member moment  **
**                                                           */
static void DspMemberMomB_1 ( 

Tpoint *p,   /* Point location where the moment will be displayed */
double mb,   /* Moment value */
double dx,   /* Horizontal and vertical components */
double dy)   /* of the length of the loaded member */

{
 Tpoint tip, arrow[3], orig;
 double ang, ang1, ang2;

 orig.x = 0.0;
 orig.y = 0.0;
 arrow[0].x = - ( size_n * 0.10 );
 arrow[0].y = + ( size_n * 0.20 );
 arrow[1].x = 0.0;
 arrow[1].y = 0.0;
 arrow[2].x = + ( size_n * 0.10 );
 arrow[2].y = + ( size_n * 0.20 );
 DspUtlRotationPoints( PI/4.0, &orig, arrow, 3 );

 orig.x = size_m*0.4;
 orig.y = 0.0;
 DspUtlChangeSystemLG( dx, dy, p, &orig, 1 );

 tip.x = -size_m*0.5;
 tip.y = -size_m*sin60;
 arrow[0].x += tip.x;
 arrow[0].y += tip.y;
 arrow[1].x += tip.x;
 arrow[1].y += tip.y;
 arrow[2].x += tip.x;
 arrow[2].y += tip.y;
 DspUtlChangeSystemLG( dx, dy, &orig, arrow, 3 );

 /* draw the moment */

 ang = DspUtlArcTg( dy, dx );
 ang1 = ToDeg( ang + 2.0*PI/3.0 );
 ang2 = ToDeg( ang - 2.0*PI/3.0 );

 GraArc ( &orig, size_m, ang1, ang2 );
 GraSetFillIntStyle ( GRA_SOLID );
 GraFillArea ( 3, arrow );

 /* display load value */

 if( VisLoadVal == ON )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;
  int    align;

  sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.moment),
                   FtoolConvFromRefUnit(Ftool.unt.moment, mb) );
  FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.moment] );

  shift = 0.05 * size_m;
  pos.x = tip.x - shift;
  pos.y = tip.y;
  DspUtlChangeSystemLG( dx, dy, &orig, &pos, 1 );

  if( DspUtlDefOrientation( dx, dy ) )
  {
   align = GRA_NORTH_EAST;
  }
  else
  {
   align = GRA_SOUTH_WEST;
  }

  if( DspUtlDefOrientation( dx, dy ) )
  {
   charup.x = -dy;
   charup.y = dx;
  }
  else
  {
   charup.x = dy;
   charup.y = -dx;
  }
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( align );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                           **
**  This function displays the negative final member moment  **
**                                                           */
static void DspMemberMomB_2 ( 

Tpoint *p,   /* Point location where the moment will be displayed */
double mb,   /* Moment value */
double dx,   /* Horizontal and vertical components */
double dy)   /* of the length of the loaded member */

{
 Tpoint tip, arrow[3], orig;
 double ang, ang1, ang2;

 orig.x = 0.0;
 orig.y = 0.0;
 arrow[0].x = + ( size_n * 0.10 );
 arrow[0].y = - ( size_n * 0.20 );
 arrow[1].x = 0.0;
 arrow[1].y = 0.0;
 arrow[2].x = - ( size_n * 0.10 );
 arrow[2].y = - ( size_n * 0.20 );
 DspUtlRotationPoints( -PI/4.0, &orig, arrow, 3 );

 orig.x = size_m*0.4;
 orig.y = 0.0;
 DspUtlChangeSystemLG( dx, dy, p, &orig, 1 );

 tip.x = -size_m*0.5;
 tip.y = size_m*sin60;
 arrow[0].x += tip.x;
 arrow[0].y += tip.y;
 arrow[1].x += tip.x;
 arrow[1].y += tip.y;
 arrow[2].x += tip.x;
 arrow[2].y += tip.y;
 DspUtlChangeSystemLG( dx, dy, &orig, arrow, 3 );

 /* draw the moment */

 ang = DspUtlArcTg( dy, dx );
 ang1 = ToDeg( ang + 2.0*PI/3.0 );
 ang2 = ToDeg( ang - 2.0*PI/3.0 );

 GraArc ( &orig, size_m, ang1, ang2 );
 GraSetFillIntStyle ( GRA_SOLID );
 GraFillArea ( 3, arrow );

 /* display load value */

 if( VisLoadVal == ON )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;
  int    align;

  sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.moment),
                   FtoolConvFromRefUnit(Ftool.unt.moment, fabs(mb)) );
  FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.moment] );

  shift = 0.05 * size_m;
  pos.x = tip.x - shift;
  pos.y = tip.y;
  DspUtlChangeSystemLG( dx, dy, &orig, &pos, 1 );

  if( DspUtlDefOrientation( dx, dy ) )
  {
   align = GRA_SOUTH_EAST;
  }
  else
  {
   align = GRA_NORTH_WEST;
  }

  if( DspUtlDefOrientation( dx, dy ) )
  {
   charup.x = -dy;
   charup.y = dx;
  }
  else
  {
   charup.x = dy;
   charup.y = -dx;
  }
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( align );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                              **
**  This function displays the reaction forces  **
**                                              */

void DspSupReact (

 Tpoint  *p,      /* Point location where the forces will be displayed */
 double  px,      /* The horizontal force value                        */
 double  py,      /* The vertical force value                          */
 double  mz,      /* The moment value                                  */
 double  offsetx, /* Offset to display horizontal reaction force       */
 double  offsety, /* Offset to display vertical reaction force         */
 int     colour)  /* Colour's forces draw                              */

{
  Tpoint pt_loc;

  if ( px || py || mz )
  {
    size_txt = dsp_sizetxt;
    GraSetTextHeight( size_txt );

    GraSetLineColor (colour);
    GraSetFillColor (colour);
    GraSetTextColor (colour);

    size_n = dsp_sizenf;
    size_m = dsp_sizemom;

    if (px)
    {
      pt_loc.x = p->x + offsetx;
      pt_loc.y = p->y;
      if ( px>0 )
        DspReactHor_1 (&pt_loc, px);
      else
        DspReactHor_2 (&pt_loc, px);
    }

    if (py)
    {
      pt_loc.x = p->x;
      pt_loc.y = p->y + offsety;
      if ( py>0 )
        DspReactVert_1 (&pt_loc, py);
      else
        DspReactVert_2 (&pt_loc, py);
    }

    if (mz)
    {
      if ( mz>0 )
        DspReactMom_1 (p, mz);
      else
        DspReactMom_2 (p, mz);
    }
  }
}


/*                                                                 **
**  This function displays the positive horizontal reaction force  **
**                                                                 */
static void DspReactHor_1 (

Tpoint *p,   /* Point location where the force will be displayed */
double px)   /* Horizontal reaction force value */

{
  static Tpoint linep1[2], linep2[3], linep3[2];

  /* build the force */

  linep1[0].x = ( p->x ) - ( size_n );
  linep1[0].y = ( p->y );
  linep1[1].x = ( p->x ) - ( size_n * 0.2 );
  linep1[1].y = ( p->y );

  linep2[0].x = linep1[1].x - ( size_n * 0.20 );
  linep2[0].y = linep1[1].y + ( size_n * 0.10 );
  linep2[1].x = linep1[1].x;
  linep2[1].y = linep1[1].y;
  linep2[2].x = linep1[1].x - ( size_n * 0.20 );
  linep2[2].y = linep1[1].y - ( size_n * 0.10 );

  linep3[0].x = (linep1[0].x + linep1[1].x) * 0.5 + (size_n * 0.005) ;
  linep3[0].y = linep1[0].y + ( size_n * 0.10 );
  linep3[1].x = linep3[0].x;
  linep3[1].y = linep1[0].y - ( size_n * 0.10 );

  /* draw the force */

  GraPolyLine ( 2, linep1 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, linep2 );
  GraPolyLine ( 2, linep3 );

 /* display reaction value */

 if( Ftool.vis.reactval == ON )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.force),
                   FtoolConvFromRefUnit(Ftool.unt.force, px) );
  FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.force] );

  shift = 0.10 * size_n;
  pos.x = p->x - ( size_n * 0.50 ) - shift;
  pos.y = p->y - shift;

  charup.x = 0.0;
  charup.y = 1.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_NORTH_EAST );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                                 **
**  This function displays the negative horizontal reaction force  **
**                                                                 */
static void DspReactHor_2 (

Tpoint *p,   /* Point location where the force will be displayed */
double px)   /* Horizontal reaction force value */

{
  static Tpoint linep1[2], linep2[3], linep3[2];

  /* build the force */

  linep1[0].x = ( p->x ) - ( size_n );
  linep1[0].y = ( p->y );
  linep1[1].x = ( p->x ) - ( size_n * 0.2 );
  linep1[1].y = ( p->y );

  linep2[0].x = linep1[0].x + ( size_n * 0.20 );
  linep2[0].y = linep1[0].y + ( size_n * 0.10 );
  linep2[1].x = linep1[0].x;
  linep2[1].y = linep1[0].y;
  linep2[2].x = linep1[0].x + ( size_n * 0.20 );
  linep2[2].y = linep1[0].y - ( size_n * 0.10 );

  linep3[0].x = (linep1[0].x + linep1[1].x) * 0.5 - (size_n * 0.005) ;
  linep3[0].y = linep1[0].y + ( size_n * 0.10 );
  linep3[1].x = linep3[0].x;
  linep3[1].y = linep1[0].y - ( size_n * 0.10 );

  /* draw the force */

  GraPolyLine ( 2, linep1 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, linep2 );
  GraPolyLine ( 2, linep3 );

 /* display reaction value */

 if( Ftool.vis.reactval == ON )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.force),
                   FtoolConvFromRefUnit(Ftool.unt.force, fabs(px)) );
  FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.force] );

  shift = 0.10 * size_n;
  pos.x = p->x - ( size_n * 0.50 ) - shift;
  pos.y = p->y - shift;

  charup.x = 0.0;
  charup.y = 1.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_NORTH_EAST );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                               **
**  This function displays the positive vertical reaction force  **
**                                                               */
static void DspReactVert_1 (

Tpoint *p,   /* Point location where the force will be displayed */
double py)   /* Vertical reaction force value */

{
  static Tpoint linep1[2], linep2[3], linep3[2];

  /* build the force */

  linep1[0].x = ( p->x );
  linep1[0].y = ( p->y ) - ( size_n );
  linep1[1].x = ( p->x );
  linep1[1].y = ( p->y ) - ( size_n * 0.2 );

  linep2[0].x = linep1[1].x - ( size_n * 0.10 );
  linep2[0].y = linep1[1].y - ( size_n * 0.20 );
  linep2[1].x = linep1[1].x;
  linep2[1].y = linep1[1].y;
  linep2[2].x = linep1[1].x + ( size_n * 0.10 );
  linep2[2].y = linep1[1].y - ( size_n * 0.20 );

  linep3[0].x = linep1[0].x - ( size_n * 0.10 );
  linep3[0].y = (linep1[0].y + linep1[1].y) * 0.5 + (size_n * 0.005) ;
  linep3[1].x = linep1[0].x + ( size_n * 0.10 );
  linep3[1].y = linep3[0].y;

  /* draw the force */

  GraPolyLine ( 2, linep1 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, linep2 );
  GraPolyLine ( 2, linep3 );

 /* display reaction value */

 if( Ftool.vis.reactval == ON )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.force),
                   FtoolConvFromRefUnit(Ftool.unt.force, py) );
  FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.force] );

  shift = 0.15 * size_n;
  pos.x = p->x - shift;
  pos.y = p->y - ( size_n * 0.50 ) - shift;

  charup.x = -1.0;
  charup.y =  0.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_BASE_RIGHT );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                               **
**  This function displays the negative vertical reaction force  **
**                                                               */
static void DspReactVert_2 (

Tpoint *p,   /* Point location where the force will be displayed */
double py)   /* Vertical reaction force value */

{
  static Tpoint linep1[2], linep2[3], linep3[2];

  /* build the force */

  linep1[0].x = ( p->x );
  linep1[0].y = ( p->y ) - ( size_n );
  linep1[1].x = ( p->x );
  linep1[1].y = ( p->y ) - ( size_n * 0.2 );

  linep2[0].x = linep1[0].x - ( size_n * 0.10 );
  linep2[0].y = linep1[0].y + ( size_n * 0.20 );
  linep2[1].x = linep1[0].x;
  linep2[1].y = linep1[0].y;
  linep2[2].x = linep1[0].x + ( size_n * 0.10 );
  linep2[2].y = linep1[0].y + ( size_n * 0.20 );

  linep3[0].x = linep1[0].x - ( size_n * 0.10 );
  linep3[0].y = (linep1[0].y + linep1[1].y) * 0.5 - (size_n * 0.005) ;
  linep3[1].x = linep1[0].x + ( size_n * 0.10 );
  linep3[1].y = linep3[0].y;

  /* draw the force */

  GraPolyLine ( 2, linep1 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, linep2 );
  GraPolyLine ( 2, linep3 );

 /* display reaction value */

 if( Ftool.vis.reactval == ON )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.force),
                   FtoolConvFromRefUnit(Ftool.unt.force, fabs(py)) );
  FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.force] );

  shift = 0.15 * size_n;
  pos.x = p->x - shift;
  pos.y = p->y - ( size_n * 0.50 ) - shift;

  charup.x = -1.0;
  charup.y =  0.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_BASE_RIGHT );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                       **
**  This function displays the positive reaction moment  **
**                                                       */
static void DspReactMom_1 (

Tpoint *p,   /* Point location where the moment will be displayed */
double mz)   /* Reaction moment value */

{
  static Tpoint tip, arrow[3], dash[2];

  tip.x = p->x + size_m;
  tip.y = p->y;

  arrow[0].x = tip.x + ( size_n * 0.10 );
  arrow[0].y = tip.y - ( size_n * 0.20 );
  arrow[1].x = tip.x;
  arrow[1].y = tip.y;
  arrow[2].x = tip.x - ( size_n * 0.10 );
  arrow[2].y = tip.y - ( size_n * 0.20 );

  DspUtlRotationPoints( -PI/12.0, &tip, arrow, 3 );

  dash[0].x = p->x;
  dash[0].y = p->y - size_m + ( size_n * 0.10 );
  dash[1].x = dash[0].x;
  dash[1].y = p->y - size_m - ( size_n * 0.10 );

  DspUtlRotationPoints( PI/12.0, p, dash, 2 );

  /* draw the moment */

  GraArc ( p, size_m, 180.0, 360.0 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, arrow );
  GraPolyLine ( 2, dash );

 /* display reaction value */

 if( Ftool.vis.reactval == ON )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.moment),
                   FtoolConvFromRefUnit(Ftool.unt.moment, mz) );
  FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.moment] );

  shift = 0.10 * size_m;
  pos.x = p->x + (0.866 * size_m) + shift;
  pos.y = p->y - (0.500 * size_m) - shift;

  charup.x = 0.0;
  charup.y = 1.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_NORTH_WEST );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


/*                                                       **
**  This function displays the negative reaction moment  **
**                                                       */
static void DspReactMom_2 (

Tpoint *p,   /* Point location where the moment will be displayed */
double mz)   /* Reaction moment value */

{
  static Tpoint tip, arrow[3], dash[2];

  tip.x = p->x - size_m;
  tip.y = p->y;

  arrow[0].x = tip.x + ( size_n * 0.10 );
  arrow[0].y = tip.y - ( size_n * 0.20 );
  arrow[1].x = tip.x;
  arrow[1].y = tip.y;
  arrow[2].x = tip.x - ( size_n * 0.10 );
  arrow[2].y = tip.y - ( size_n * 0.20 );

  DspUtlRotationPoints( PI/12.0, &tip, arrow, 3 );

  dash[0].x = p->x;
  dash[0].y = p->y - size_m + ( size_n * 0.10 );
  dash[1].x = dash[0].x;
  dash[1].y = p->y - size_m - ( size_n * 0.10 );

  DspUtlRotationPoints( -PI/12.0, p, dash, 2 );

  /* draw the moment */

  GraArc ( p, size_m, 180.0, 360.0 );
  GraSetFillIntStyle ( GRA_SOLID );
  GraFillArea ( 3, arrow );
  GraPolyLine ( 2, dash );

 /* display reaction value */

 if( Ftool.vis.reactval == ON )
 {
  Tpoint charup;
  Tpoint pos;
  double shift;

  sprintf( dvalue, FtoolNumberFormat(Ftool.nbf.moment),
                   FtoolConvFromRefUnit(Ftool.unt.moment, fabs(mz)) );
  FtoolShrinkExp( dvalue );
  sprintf( dtext, "%s %s", dvalue, funitsymbol[Ftool.unt.moment] );

  shift = 0.10 * size_m;
  pos.x = p->x + (0.866 * size_m) + shift;
  pos.y = p->y - (0.500 * size_m) - shift;

  charup.x = 0.0;
  charup.y = 1.0;
  GraSetTextCharUp( charup.x, charup.y );
  GraSetTextAlign( GRA_NORTH_WEST );
  GraBackOpacity( GRA_OPAQUE );
  GraText( &pos, dtext );
  GraBackOpacity( GRA_TRANSPARENT );
 }
}


#endif
